s3-param Make lp_statedir() const
[samba.git] / source3 / param / loadparm.c
1 /* 
2    Unix SMB/CIFS implementation.
3    Parameter loading functions
4    Copyright (C) Karl Auer 1993-1998
5
6    Largely re-written by Andrew Tridgell, September 1994
7
8    Copyright (C) Simo Sorce 2001
9    Copyright (C) Alexander Bokovoy 2002
10    Copyright (C) Stefan (metze) Metzmacher 2002
11    Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003
12    Copyright (C) Michael Adam 2008
13
14    This program is free software; you can redistribute it and/or modify
15    it under the terms of the GNU General Public License as published by
16    the Free Software Foundation; either version 3 of the License, or
17    (at your option) any later version.
18
19    This program is distributed in the hope that it will be useful,
20    but WITHOUT ANY WARRANTY; without even the implied warranty of
21    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22    GNU General Public License for more details.
23
24    You should have received a copy of the GNU General Public License
25    along with this program.  If not, see <http://www.gnu.org/licenses/>.
26 */
27
28 /*
29  *  Load parameters.
30  *
31  *  This module provides suitable callback functions for the params
32  *  module. It builds the internal table of service details which is
33  *  then used by the rest of the server.
34  *
35  * To add a parameter:
36  *
37  * 1) add it to the global or service structure definition
38  * 2) add it to the parm_table
39  * 3) add it to the list of available functions (eg: using FN_GLOBAL_STRING())
40  * 4) If it's a global then initialise it in init_globals. If a local
41  *    (ie. service) parameter then initialise it in the sDefault structure
42  *  
43  *
44  * Notes:
45  *   The configuration file is processed sequentially for speed. It is NOT
46  *   accessed randomly as happens in 'real' Windows. For this reason, there
47  *   is a fair bit of sequence-dependent code here - ie., code which assumes
48  *   that certain things happen before others. In particular, the code which
49  *   happens at the boundary between sections is delicately poised, so be
50  *   careful!
51  *
52  */
53
54 #include "includes.h"
55 #include "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_CONST_STRING(lp_smb_ports, &Globals.smb_ports)
5568 FN_GLOBAL_CONST_STRING(lp_dos_charset, &Globals.dos_charset)
5569 FN_GLOBAL_CONST_STRING(lp_unix_charset, &Globals.unix_charset)
5570 FN_GLOBAL_CONST_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_CONST_STRING(lp_smb_passwd_file, &Globals.szSMBPasswdFile)
5574 FN_GLOBAL_CONST_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_CONST_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 const char *lp_statedir(void) {
5587         if ((strcmp(get_dyn_STATEDIR(), get_dyn_LOCKDIR()) != 0) ||
5588             (strcmp(get_dyn_STATEDIR(), Globals.szStateDir) != 0))
5589                 return(*(char **)(&Globals.szStateDir) ?
5590                        *(char **)(&Globals.szStateDir) : "");
5591         else
5592                 return(*(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_CONST_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 /**
7527  * Initialize iconv conversion descriptors.
7528  *
7529  * This is called the first time it is needed, and also called again
7530  * every time the configuration is reloaded, because the charset or
7531  * codepage might have changed.
7532  **/
7533 static void init_iconv(void)
7534 {
7535         global_iconv_handle = smb_iconv_handle_reinit(NULL, lp_dos_charset(),
7536                                                       lp_unix_charset(), lp_display_charset(),
7537                                                       true, global_iconv_handle);
7538 }
7539
7540 static bool handle_charset(int snum, const char *pszParmValue, char **ptr)
7541 {
7542         if (strcmp(*ptr, pszParmValue) != 0) {
7543                 string_set(ptr, pszParmValue);
7544                 init_iconv();
7545         }
7546         return True;
7547 }
7548
7549 static bool handle_dos_charset(int snum, const char *pszParmValue, char **ptr)
7550 {
7551         bool is_utf8 = false;
7552         size_t len = strlen(pszParmValue);
7553
7554         if (len == 4 || len == 5) {
7555                 /* Don't use StrCaseCmp here as we don't want to
7556                    initialize iconv. */
7557                 if ((toupper_ascii(pszParmValue[0]) == 'U') &&
7558                     (toupper_ascii(pszParmValue[1]) == 'T') &&
7559                     (toupper_ascii(pszParmValue[2]) == 'F')) {
7560                         if (len == 4) {
7561                                 if (pszParmValue[3] == '8') {
7562                                         is_utf8 = true;
7563                                 }
7564                         } else {
7565                                 if (pszParmValue[3] == '-' &&
7566                                     pszParmValue[4] == '8') {
7567                                         is_utf8 = true;
7568                                 }
7569                         }
7570                 }
7571         }
7572
7573         if (strcmp(*ptr, pszParmValue) != 0) {
7574                 if (is_utf8) {
7575                         DEBUG(0,("ERROR: invalid DOS charset: 'dos charset' must not "
7576                                 "be UTF8, using (default value) %s instead.\n",
7577                                 DEFAULT_DOS_CHARSET));
7578                         pszParmValue = DEFAULT_DOS_CHARSET;
7579                 }
7580                 string_set(ptr, pszParmValue);
7581                 init_iconv();
7582         }
7583         return true;
7584 }
7585
7586
7587
7588 static bool handle_workgroup(int snum, const char *pszParmValue, char **ptr)
7589 {
7590         bool ret;
7591
7592         ret = set_global_myworkgroup(pszParmValue);
7593         string_set(&Globals.szWorkgroup,lp_workgroup());
7594
7595         return ret;
7596 }
7597
7598 static bool handle_netbios_scope(int snum, const char *pszParmValue, char **ptr)
7599 {
7600         bool ret;
7601
7602         ret = set_global_scope(pszParmValue);
7603         string_set(&Globals.szNetbiosScope,global_scope());
7604
7605         return ret;
7606 }
7607
7608 static bool handle_netbios_aliases(int snum, const char *pszParmValue, char **ptr)
7609 {
7610         TALLOC_FREE(Globals.szNetbiosAliases);
7611         Globals.szNetbiosAliases = str_list_make_v3(NULL, pszParmValue, NULL);
7612         return set_netbios_aliases((const char **)Globals.szNetbiosAliases);
7613 }
7614
7615 /***************************************************************************
7616  Handle the include operation.
7617 ***************************************************************************/
7618 static bool bAllowIncludeRegistry = true;
7619
7620 static bool handle_include(int snum, const char *pszParmValue, char **ptr)
7621 {
7622         char *fname;
7623
7624         if (include_depth >= MAX_INCLUDE_DEPTH) {
7625                 DEBUG(0, ("Error: Maximum include depth (%u) exceeded!\n",
7626                           include_depth));
7627                 return false;
7628         }
7629
7630         if (strequal(pszParmValue, INCLUDE_REGISTRY_NAME)) {
7631                 if (!bAllowIncludeRegistry) {
7632                         return true;
7633                 }
7634                 if (bInGlobalSection) {
7635                         bool ret;
7636                         include_depth++;
7637                         ret = process_registry_globals();
7638                         include_depth--;
7639                         return ret;
7640                 } else {
7641                         DEBUG(1, ("\"include = registry\" only effective "
7642                                   "in %s section\n", GLOBAL_NAME));
7643                         return false;
7644                 }
7645         }
7646
7647         fname = talloc_sub_basic(talloc_tos(), get_current_username(),
7648                                  current_user_info.domain,
7649                                  pszParmValue);
7650
7651         add_to_file_list(pszParmValue, fname);
7652
7653         string_set(ptr, fname);
7654
7655         if (file_exist(fname)) {
7656                 bool ret;
7657                 include_depth++;
7658                 ret = pm_process(fname, do_section, do_parameter, NULL);
7659                 include_depth--;
7660                 TALLOC_FREE(fname);
7661                 return ret;
7662         }
7663
7664         DEBUG(2, ("Can't find include file %s\n", fname));
7665         TALLOC_FREE(fname);
7666         return true;
7667 }
7668
7669 /***************************************************************************
7670  Handle the interpretation of the copy parameter.
7671 ***************************************************************************/
7672
7673 static bool handle_copy(int snum, const char *pszParmValue, char **ptr)
7674 {
7675         bool bRetval;
7676         int iTemp;
7677         struct service serviceTemp;
7678
7679         string_set(ptr, pszParmValue);
7680
7681         init_service(&serviceTemp);
7682
7683         bRetval = False;
7684
7685         DEBUG(3, ("Copying service from service %s\n", pszParmValue));
7686
7687         if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
7688                 if (iTemp == iServiceIndex) {
7689                         DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
7690                 } else {
7691                         copy_service(ServicePtrs[iServiceIndex],
7692                                      &serviceTemp,
7693                                      ServicePtrs[iServiceIndex]->copymap);
7694                         bRetval = True;
7695                 }
7696         } else {
7697                 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
7698                 bRetval = False;
7699         }
7700
7701         free_service(&serviceTemp);
7702         return (bRetval);
7703 }
7704
7705 static bool handle_ldap_debug_level(int snum, const char *pszParmValue, char **ptr)
7706 {
7707         Globals.ldap_debug_level = lp_int(pszParmValue);
7708         init_ldap_debugging();
7709         return true;
7710 }
7711
7712 /***************************************************************************
7713  Handle idmap/non unix account uid and gid allocation parameters.  The format of these
7714  parameters is:
7715
7716  [global]
7717
7718         idmap uid = 1000-1999
7719         idmap gid = 700-899
7720
7721  We only do simple parsing checks here.  The strings are parsed into useful
7722  structures in the idmap daemon code.
7723
7724 ***************************************************************************/
7725
7726 /* Some lp_ routines to return idmap [ug]id information */
7727
7728 static uid_t idmap_uid_low, idmap_uid_high;
7729 static gid_t idmap_gid_low, idmap_gid_high;
7730
7731 bool lp_idmap_uid(uid_t *low, uid_t *high)
7732 {
7733         if (idmap_uid_low == 0 || idmap_uid_high == 0)
7734                 return False;
7735
7736         if (low)
7737                 *low = idmap_uid_low;
7738
7739         if (high)
7740                 *high = idmap_uid_high;
7741
7742         return True;
7743 }
7744
7745 bool lp_idmap_gid(gid_t *low, gid_t *high)
7746 {
7747         if (idmap_gid_low == 0 || idmap_gid_high == 0)
7748                 return False;
7749
7750         if (low)
7751                 *low = idmap_gid_low;
7752
7753         if (high)
7754                 *high = idmap_gid_high;
7755
7756         return True;
7757 }
7758
7759 static bool handle_idmap_backend(int snum, const char *pszParmValue, char **ptr)
7760 {
7761         lp_do_parameter(snum, "idmap config * : backend", pszParmValue);
7762
7763         return true;
7764 }
7765
7766 /* Do some simple checks on "idmap [ug]id" parameter values */
7767
7768 static bool handle_idmap_uid(int snum, const char *pszParmValue, char **ptr)
7769 {
7770         lp_do_parameter(snum, "idmap config * : range", pszParmValue);
7771
7772         return True;
7773 }
7774
7775 static bool handle_idmap_gid(int snum, const char *pszParmValue, char **ptr)
7776 {
7777         lp_do_parameter(snum, "idmap config * : range", pszParmValue);
7778
7779         return True;
7780 }
7781
7782 /***************************************************************************
7783  Handle the DEBUG level list.
7784 ***************************************************************************/
7785
7786 static bool handle_debug_list( int snum, const char *pszParmValueIn, char **ptr )
7787 {
7788         string_set(ptr, pszParmValueIn);
7789         return debug_parse_levels(pszParmValueIn);
7790 }
7791
7792 /***************************************************************************
7793  Handle ldap suffixes - default to ldapsuffix if sub-suffixes are not defined.
7794 ***************************************************************************/
7795
7796 static const char *append_ldap_suffix( const char *str )
7797 {
7798         const char *suffix_string;
7799
7800
7801         suffix_string = talloc_asprintf(talloc_tos(), "%s,%s", str,
7802                                         Globals.szLdapSuffix );
7803         if ( !suffix_string ) {
7804                 DEBUG(0,("append_ldap_suffix: talloc_asprintf() failed!\n"));
7805                 return "";
7806         }
7807
7808         return suffix_string;
7809 }
7810
7811 const char *lp_ldap_machine_suffix(void)
7812 {
7813         if (Globals.szLdapMachineSuffix[0])
7814                 return append_ldap_suffix(Globals.szLdapMachineSuffix);
7815
7816         return lp_string(Globals.szLdapSuffix);
7817 }
7818
7819 const char *lp_ldap_user_suffix(void)
7820 {
7821         if (Globals.szLdapUserSuffix[0])
7822                 return append_ldap_suffix(Globals.szLdapUserSuffix);
7823
7824         return lp_string(Globals.szLdapSuffix);
7825 }
7826
7827 const char *lp_ldap_group_suffix(void)
7828 {
7829         if (Globals.szLdapGroupSuffix[0])
7830                 return append_ldap_suffix(Globals.szLdapGroupSuffix);
7831
7832         return lp_string(Globals.szLdapSuffix);
7833 }
7834
7835 const char *lp_ldap_idmap_suffix(void)
7836 {
7837         if (Globals.szLdapIdmapSuffix[0])
7838                 return append_ldap_suffix(Globals.szLdapIdmapSuffix);
7839
7840         return lp_string(Globals.szLdapSuffix);
7841 }
7842
7843 /****************************************************************************
7844  set the value for a P_ENUM
7845  ***************************************************************************/
7846
7847 static void lp_set_enum_parm( struct parm_struct *parm, const char *pszParmValue,
7848                               int *ptr )
7849 {
7850         int i;
7851
7852         for (i = 0; parm->enum_list[i].name; i++) {
7853                 if ( strequal(pszParmValue, parm->enum_list[i].name)) {
7854                         *ptr = parm->enum_list[i].value;
7855                         return;
7856                 }
7857         }
7858         DEBUG(0, ("WARNING: Ignoring invalid value '%s' for parameter '%s'\n",
7859                   pszParmValue, parm->label));
7860 }
7861
7862 /***************************************************************************
7863 ***************************************************************************/
7864
7865 static bool handle_printing(int snum, const char *pszParmValue, char **ptr)
7866 {
7867         static int parm_num = -1;
7868         struct service *s;
7869
7870         if ( parm_num == -1 )
7871                 parm_num = map_parameter( "printing" );
7872
7873         lp_set_enum_parm( &parm_table[parm_num], pszParmValue, (int*)ptr );
7874
7875         if ( snum < 0 )
7876                 s = &sDefault;
7877         else
7878                 s = ServicePtrs[snum];
7879
7880         init_printer_values( s );
7881
7882         return True;
7883 }
7884
7885
7886 /***************************************************************************
7887  Initialise a copymap.
7888 ***************************************************************************/
7889
7890 static void init_copymap(struct service *pservice)
7891 {
7892         int i;
7893
7894         TALLOC_FREE(pservice->copymap);
7895
7896         pservice->copymap = bitmap_talloc(NULL, NUMPARAMETERS);
7897         if (!pservice->copymap)
7898                 DEBUG(0,
7899                       ("Couldn't allocate copymap!! (size %d)\n",
7900                        (int)NUMPARAMETERS));
7901         else
7902                 for (i = 0; i < NUMPARAMETERS; i++)
7903                         bitmap_set(pservice->copymap, i);
7904 }
7905
7906 /***************************************************************************
7907  Return the local pointer to a parameter given a service struct and the
7908  pointer into the default structure.
7909 ***************************************************************************/
7910
7911 static void *lp_local_ptr(struct service *service, void *ptr)
7912 {
7913         return (void *)(((char *)service) + PTR_DIFF(ptr, &sDefault));
7914 }
7915
7916 /***************************************************************************
7917  Return the local pointer to a parameter given the service number and the 
7918  pointer into the default structure.
7919 ***************************************************************************/
7920
7921 void *lp_local_ptr_by_snum(int snum, void *ptr)
7922 {
7923         return lp_local_ptr(ServicePtrs[snum], ptr);
7924 }
7925
7926 /***************************************************************************
7927  Process a parameter for a particular service number. If snum < 0
7928  then assume we are in the globals.
7929 ***************************************************************************/
7930
7931 bool lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
7932 {
7933         int parmnum, i;
7934         void *parm_ptr = NULL;  /* where we are going to store the result */
7935         void *def_ptr = NULL;
7936         struct param_opt_struct **opt_list;
7937
7938         parmnum = map_parameter(pszParmName);
7939
7940         if (parmnum < 0) {
7941                 if (strchr(pszParmName, ':') == NULL) {
7942                         DEBUG(0, ("Ignoring unknown parameter \"%s\"\n",
7943                                   pszParmName));
7944                         return (True);
7945                 }
7946
7947                 /*
7948                  * We've got a parametric option
7949                  */
7950
7951                 opt_list = (snum < 0)
7952                         ? &Globals.param_opt : &ServicePtrs[snum]->param_opt;
7953                 set_param_opt(opt_list, pszParmName, pszParmValue, 0);
7954
7955                 return (True);
7956         }
7957
7958         /* if it's already been set by the command line, then we don't
7959            override here */
7960         if (parm_table[parmnum].flags & FLAG_CMDLINE) {
7961                 return true;
7962         }
7963
7964         if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
7965                 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
7966                           pszParmName));
7967         }
7968
7969         def_ptr = parm_table[parmnum].ptr;
7970
7971         /* we might point at a service, the default service or a global */
7972         if (snum < 0) {
7973                 parm_ptr = def_ptr;
7974         } else {
7975                 if (parm_table[parmnum].p_class == P_GLOBAL) {
7976                         DEBUG(0,
7977                               ("Global parameter %s found in service section!\n",
7978                                pszParmName));
7979                         return (True);
7980                 }
7981                 parm_ptr = lp_local_ptr_by_snum(snum, def_ptr);
7982         }
7983
7984         if (snum >= 0) {
7985                 if (!ServicePtrs[snum]->copymap)
7986                         init_copymap(ServicePtrs[snum]);
7987
7988                 /* this handles the aliases - set the copymap for other entries with
7989                    the same data pointer */
7990                 for (i = 0; parm_table[i].label; i++)
7991                         if (parm_table[i].ptr == parm_table[parmnum].ptr)
7992                                 bitmap_clear(ServicePtrs[snum]->copymap, i);
7993         }
7994
7995         /* if it is a special case then go ahead */
7996         if (parm_table[parmnum].special) {
7997                 return parm_table[parmnum].special(snum, pszParmValue,
7998                                                    (char **)parm_ptr);
7999         }
8000
8001         /* now switch on the type of variable it is */
8002         switch (parm_table[parmnum].type)
8003         {
8004                 case P_BOOL:
8005                         *(bool *)parm_ptr = lp_bool(pszParmValue);
8006                         break;
8007
8008                 case P_BOOLREV:
8009                         *(bool *)parm_ptr = !lp_bool(pszParmValue);
8010                         break;
8011
8012                 case P_INTEGER:
8013                         *(int *)parm_ptr = lp_int(pszParmValue);
8014                         break;
8015
8016                 case P_CHAR:
8017                         *(char *)parm_ptr = *pszParmValue;
8018                         break;
8019
8020                 case P_OCTAL:
8021                         i = sscanf(pszParmValue, "%o", (int *)parm_ptr);
8022                         if ( i != 1 ) {
8023                             DEBUG ( 0, ("Invalid octal number %s\n", pszParmName ));
8024                         }
8025                         break;
8026
8027                 case P_LIST:
8028                         TALLOC_FREE(*((char ***)parm_ptr));
8029                         *(char ***)parm_ptr = str_list_make_v3(
8030                                 NULL, pszParmValue, NULL);
8031                         break;
8032
8033                 case P_STRING:
8034                         string_set((char **)parm_ptr, pszParmValue);
8035                         break;
8036
8037                 case P_USTRING:
8038                         string_set((char **)parm_ptr, pszParmValue);
8039                         strupper_m(*(char **)parm_ptr);
8040                         break;
8041
8042                 case P_ENUM:
8043                         lp_set_enum_parm( &parm_table[parmnum], pszParmValue, (int*)parm_ptr );
8044                         break;
8045                 case P_SEP:
8046                         break;
8047         }
8048
8049         return (True);
8050 }
8051
8052 /***************************************************************************
8053 set a parameter, marking it with FLAG_CMDLINE. Parameters marked as
8054 FLAG_CMDLINE won't be overridden by loads from smb.conf.
8055 ***************************************************************************/
8056
8057 static bool lp_set_cmdline_helper(const char *pszParmName, const char *pszParmValue, bool store_values)
8058 {
8059         int parmnum, i;
8060         parmnum = map_parameter(pszParmName);
8061         if (parmnum >= 0) {
8062                 parm_table[parmnum].flags &= ~FLAG_CMDLINE;
8063                 if (!lp_do_parameter(-1, pszParmName, pszParmValue)) {
8064                         return false;
8065                 }
8066                 parm_table[parmnum].flags |= FLAG_CMDLINE;
8067
8068                 /* we have to also set FLAG_CMDLINE on aliases.  Aliases must
8069                  * be grouped in the table, so we don't have to search the
8070                  * whole table */
8071                 for (i=parmnum-1;i>=0 && parm_table[i].ptr == parm_table[parmnum].ptr;i--) {
8072                         parm_table[i].flags |= FLAG_CMDLINE;
8073                 }
8074                 for (i=parmnum+1;i<NUMPARAMETERS && parm_table[i].ptr == parm_table[parmnum].ptr;i++) {
8075                         parm_table[i].flags |= FLAG_CMDLINE;
8076                 }
8077
8078                 if (store_values) {
8079                         store_lp_set_cmdline(pszParmName, pszParmValue);
8080                 }
8081                 return true;
8082         }
8083
8084         /* it might be parametric */
8085         if (strchr(pszParmName, ':') != NULL) {
8086                 set_param_opt(&Globals.param_opt, pszParmName, pszParmValue, FLAG_CMDLINE);
8087                 if (store_values) {
8088                         store_lp_set_cmdline(pszParmName, pszParmValue);
8089                 }
8090                 return true;
8091         }
8092
8093         DEBUG(0, ("Ignoring unknown parameter \"%s\"\n",  pszParmName));
8094         return true;
8095 }
8096
8097 bool lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
8098 {
8099         return lp_set_cmdline_helper(pszParmName, pszParmValue, true);
8100 }
8101
8102 /***************************************************************************
8103  Process a parameter.
8104 ***************************************************************************/
8105
8106 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
8107                          void *userdata)
8108 {
8109         if (!bInGlobalSection && bGlobalOnly)
8110                 return (True);
8111
8112         DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
8113
8114         return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
8115                                 pszParmName, pszParmValue));
8116 }
8117
8118 /*
8119   set a option from the commandline in 'a=b' format. Use to support --option
8120 */
8121 bool lp_set_option(const char *option)
8122 {
8123         char *p, *s;
8124         bool ret;
8125
8126         s = talloc_strdup(NULL, option);
8127         if (!s) {
8128                 return false;
8129         }
8130
8131         p = strchr(s, '=');
8132         if (!p) {
8133                 talloc_free(s);
8134                 return false;
8135         }
8136
8137         *p = 0;
8138
8139         /* skip white spaces after the = sign */
8140         do {
8141                 p++;
8142         } while (*p == ' ');
8143
8144         ret = lp_set_cmdline(s, p);
8145         talloc_free(s);
8146         return ret;
8147 }
8148
8149 /**************************************************************************
8150  Print a parameter of the specified type.
8151 ***************************************************************************/
8152
8153 static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
8154 {
8155         int i;
8156         switch (p->type)
8157         {
8158                 case P_ENUM:
8159                         for (i = 0; p->enum_list[i].name; i++) {
8160                                 if (*(int *)ptr == p->enum_list[i].value) {
8161                                         fprintf(f, "%s",
8162                                                 p->enum_list[i].name);
8163                                         break;
8164                                 }
8165                         }
8166                         break;
8167
8168                 case P_BOOL:
8169                         fprintf(f, "%s", BOOLSTR(*(bool *)ptr));
8170                         break;
8171
8172                 case P_BOOLREV:
8173                         fprintf(f, "%s", BOOLSTR(!*(bool *)ptr));
8174                         break;
8175
8176                 case P_INTEGER:
8177                         fprintf(f, "%d", *(int *)ptr);
8178                         break;
8179
8180                 case P_CHAR:
8181                         fprintf(f, "%c", *(char *)ptr);
8182                         break;
8183
8184                 case P_OCTAL: {
8185                         char *o = octal_string(*(int *)ptr);
8186                         fprintf(f, "%s", o);
8187                         TALLOC_FREE(o);
8188                         break;
8189                 }
8190
8191                 case P_LIST:
8192                         if ((char ***)ptr && *(char ***)ptr) {
8193                                 char **list = *(char ***)ptr;
8194                                 for (; *list; list++) {
8195                                         /* surround strings with whitespace in double quotes */
8196                                         if ( strchr_m( *list, ' ' ) )
8197                                                 fprintf(f, "\"%s\"%s", *list, ((*(list+1))?", ":""));
8198                                         else
8199                                                 fprintf(f, "%s%s", *list, ((*(list+1))?", ":""));
8200                                 }
8201                         }
8202                         break;
8203
8204                 case P_STRING:
8205                 case P_USTRING:
8206                         if (*(char **)ptr) {
8207                                 fprintf(f, "%s", *(char **)ptr);
8208                         }
8209                         break;
8210                 case P_SEP:
8211                         break;
8212         }
8213 }
8214
8215 /***************************************************************************
8216  Check if two parameters are equal.
8217 ***************************************************************************/
8218
8219 static bool equal_parameter(parm_type type, void *ptr1, void *ptr2)
8220 {
8221         switch (type) {
8222                 case P_BOOL:
8223                 case P_BOOLREV:
8224                         return (*((bool *)ptr1) == *((bool *)ptr2));
8225
8226                 case P_INTEGER:
8227                 case P_ENUM:
8228                 case P_OCTAL:
8229                         return (*((int *)ptr1) == *((int *)ptr2));
8230
8231                 case P_CHAR:
8232                         return (*((char *)ptr1) == *((char *)ptr2));
8233
8234                 case P_LIST:
8235                         return str_list_equal(*(const char ***)ptr1, *(const char ***)ptr2);
8236
8237                 case P_STRING:
8238                 case P_USTRING:
8239                 {
8240                         char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
8241                         if (p1 && !*p1)
8242                                 p1 = NULL;
8243                         if (p2 && !*p2)
8244                                 p2 = NULL;
8245                         return (p1 == p2 || strequal(p1, p2));
8246                 }
8247                 case P_SEP:
8248                         break;
8249         }
8250         return (False);
8251 }
8252
8253 /***************************************************************************
8254  Initialize any local varients in the sDefault table.
8255 ***************************************************************************/
8256
8257 void init_locals(void)
8258 {
8259         /* None as yet. */
8260 }
8261
8262 /***************************************************************************
8263  Process a new section (service). At this stage all sections are services.
8264  Later we'll have special sections that permit server parameters to be set.
8265  Returns True on success, False on failure. 
8266 ***************************************************************************/
8267
8268 static bool do_section(const char *pszSectionName, void *userdata)
8269 {
8270         bool bRetval;
8271         bool isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
8272                          (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
8273         bRetval = False;
8274
8275         /* if we were in a global section then do the local inits */
8276         if (bInGlobalSection && !isglobal)
8277                 init_locals();
8278
8279         /* if we've just struck a global section, note the fact. */
8280         bInGlobalSection = isglobal;
8281
8282         /* check for multiple global sections */
8283         if (bInGlobalSection) {
8284                 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
8285                 return (True);
8286         }
8287
8288         if (!bInGlobalSection && bGlobalOnly)
8289                 return (True);
8290
8291         /* if we have a current service, tidy it up before moving on */
8292         bRetval = True;
8293
8294         if (iServiceIndex >= 0)
8295                 bRetval = service_ok(iServiceIndex);
8296
8297         /* if all is still well, move to the next record in the services array */
8298         if (bRetval) {
8299                 /* We put this here to avoid an odd message order if messages are */
8300                 /* issued by the post-processing of a previous section. */
8301                 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
8302
8303                 if ((iServiceIndex = add_a_service(&sDefault, pszSectionName))
8304                     < 0) {
8305                         DEBUG(0, ("Failed to add a new service\n"));
8306                         return (False);
8307                 }
8308                 /* Clean all parametric options for service */
8309                 /* They will be added during parsing again */
8310                 free_param_opts(&ServicePtrs[iServiceIndex]->param_opt);
8311         }
8312
8313         return (bRetval);
8314 }
8315
8316
8317 /***************************************************************************
8318  Determine if a partcular base parameter is currentl set to the default value.
8319 ***************************************************************************/
8320
8321 static bool is_default(int i)
8322 {
8323         if (!defaults_saved)
8324                 return False;
8325         switch (parm_table[i].type) {
8326                 case P_LIST:
8327                         return str_list_equal((const char **)parm_table[i].def.lvalue, 
8328                                                 *(const char ***)parm_table[i].ptr);
8329                 case P_STRING:
8330                 case P_USTRING:
8331                         return strequal(parm_table[i].def.svalue,
8332                                         *(char **)parm_table[i].ptr);
8333                 case P_BOOL:
8334                 case P_BOOLREV:
8335                         return parm_table[i].def.bvalue ==
8336                                 *(bool *)parm_table[i].ptr;
8337                 case P_CHAR:
8338                         return parm_table[i].def.cvalue ==
8339                                 *(char *)parm_table[i].ptr;
8340                 case P_INTEGER:
8341                 case P_OCTAL:
8342                 case P_ENUM:
8343                         return parm_table[i].def.ivalue ==
8344                                 *(int *)parm_table[i].ptr;
8345                 case P_SEP:
8346                         break;
8347         }
8348         return False;
8349 }
8350
8351 /***************************************************************************
8352 Display the contents of the global structure.
8353 ***************************************************************************/
8354
8355 static void dump_globals(FILE *f)
8356 {
8357         int i;
8358         struct param_opt_struct *data;
8359
8360         fprintf(f, "[global]\n");
8361
8362         for (i = 0; parm_table[i].label; i++)
8363                 if (parm_table[i].p_class == P_GLOBAL &&
8364                     !(parm_table[i].flags & FLAG_META) &&
8365                     parm_table[i].ptr &&
8366                     (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
8367                         if (defaults_saved && is_default(i))
8368                                 continue;
8369                         fprintf(f, "\t%s = ", parm_table[i].label);
8370                         print_parameter(&parm_table[i], parm_table[i].ptr, f);
8371                         fprintf(f, "\n");
8372         }
8373         if (Globals.param_opt != NULL) {
8374                 data = Globals.param_opt;
8375                 while(data) {
8376                         fprintf(f, "\t%s = %s\n", data->key, data->value);
8377                         data = data->next;
8378                 }
8379         }
8380
8381 }
8382
8383 /***************************************************************************
8384  Return True if a local parameter is currently set to the global default.
8385 ***************************************************************************/
8386
8387 bool lp_is_default(int snum, struct parm_struct *parm)
8388 {
8389         int pdiff = PTR_DIFF(parm->ptr, &sDefault);
8390
8391         return equal_parameter(parm->type,
8392                                ((char *)ServicePtrs[snum]) + pdiff,
8393                                ((char *)&sDefault) + pdiff);
8394 }
8395
8396 /***************************************************************************
8397  Display the contents of a single services record.
8398 ***************************************************************************/
8399
8400 static void dump_a_service(struct service *pService, FILE * f)
8401 {
8402         int i;
8403         struct param_opt_struct *data;
8404
8405         if (pService != &sDefault)
8406                 fprintf(f, "[%s]\n", pService->szService);
8407
8408         for (i = 0; parm_table[i].label; i++) {
8409
8410                 if (parm_table[i].p_class == P_LOCAL &&
8411                     !(parm_table[i].flags & FLAG_META) &&
8412                     parm_table[i].ptr &&
8413                     (*parm_table[i].label != '-') &&
8414                     (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) 
8415                 {
8416                         int pdiff = PTR_DIFF(parm_table[i].ptr, &sDefault);
8417
8418                         if (pService == &sDefault) {
8419                                 if (defaults_saved && is_default(i))
8420                                         continue;
8421                         } else {
8422                                 if (equal_parameter(parm_table[i].type,
8423                                                     ((char *)pService) +
8424                                                     pdiff,
8425                                                     ((char *)&sDefault) +
8426                                                     pdiff))
8427                                         continue;
8428                         }
8429
8430                         fprintf(f, "\t%s = ", parm_table[i].label);
8431                         print_parameter(&parm_table[i],
8432                                         ((char *)pService) + pdiff, f);
8433                         fprintf(f, "\n");
8434                 }
8435         }
8436
8437                 if (pService->param_opt != NULL) {
8438                         data = pService->param_opt;
8439                         while(data) {
8440                                 fprintf(f, "\t%s = %s\n", data->key, data->value);
8441                                 data = data->next;
8442                         }
8443                 }
8444 }
8445
8446 /***************************************************************************
8447  Display the contents of a parameter of a single services record.
8448 ***************************************************************************/
8449
8450 bool dump_a_parameter(int snum, char *parm_name, FILE * f, bool isGlobal)
8451 {
8452         int i;
8453         bool result = False;
8454         parm_class p_class;
8455         unsigned flag = 0;
8456         fstring local_parm_name;
8457         char *parm_opt;
8458         const char *parm_opt_value;
8459
8460         /* check for parametrical option */
8461         fstrcpy( local_parm_name, parm_name);
8462         parm_opt = strchr( local_parm_name, ':');
8463
8464         if (parm_opt) {
8465                 *parm_opt = '\0';
8466                 parm_opt++;
8467                 if (strlen(parm_opt)) {
8468                         parm_opt_value = lp_parm_const_string( snum,
8469                                 local_parm_name, parm_opt, NULL);
8470                         if (parm_opt_value) {
8471                                 printf( "%s\n", parm_opt_value);
8472                                 result = True;
8473                         }
8474                 }
8475                 return result;
8476         }
8477
8478         /* check for a key and print the value */
8479         if (isGlobal) {
8480                 p_class = P_GLOBAL;
8481                 flag = FLAG_GLOBAL;
8482         } else
8483                 p_class = P_LOCAL;
8484
8485         for (i = 0; parm_table[i].label; i++) {
8486                 if (strwicmp(parm_table[i].label, parm_name) == 0 &&
8487                     !(parm_table[i].flags & FLAG_META) &&
8488                     (parm_table[i].p_class == p_class || parm_table[i].flags & flag) &&
8489                     parm_table[i].ptr &&
8490                     (*parm_table[i].label != '-') &&
8491                     (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) 
8492                 {
8493                         void *ptr;
8494
8495                         if (isGlobal) {
8496                                 ptr = parm_table[i].ptr;
8497                         } else {
8498                                 struct service *pService = ServicePtrs[snum];
8499                                 ptr = ((char *)pService) +
8500                                         PTR_DIFF(parm_table[i].ptr, &sDefault);
8501                         }
8502
8503                         print_parameter(&parm_table[i],
8504                                         ptr, f);
8505                         fprintf(f, "\n");
8506                         result = True;
8507                         break;
8508                 }
8509         }
8510
8511         return result;
8512 }
8513
8514 /***************************************************************************
8515  Return info about the requested parameter (given as a string).
8516  Return NULL when the string is not a valid parameter name.
8517 ***************************************************************************/
8518
8519 struct parm_struct *lp_get_parameter(const char *param_name)
8520 {
8521         int num = map_parameter(param_name);
8522
8523         if (num < 0) {
8524                 return NULL;
8525         }
8526
8527         return &parm_table[num];
8528 }
8529
8530 /***************************************************************************
8531  Return info about the next parameter in a service.
8532  snum==GLOBAL_SECTION_SNUM gives the globals.
8533  Return NULL when out of parameters.
8534 ***************************************************************************/
8535
8536 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
8537 {
8538         if (snum < 0) {
8539                 /* do the globals */
8540                 for (; parm_table[*i].label; (*i)++) {
8541                         if (parm_table[*i].p_class == P_SEPARATOR)
8542                                 return &parm_table[(*i)++];
8543
8544                         if (!parm_table[*i].ptr
8545                             || (*parm_table[*i].label == '-'))
8546                                 continue;
8547
8548                         if ((*i) > 0
8549                             && (parm_table[*i].ptr ==
8550                                 parm_table[(*i) - 1].ptr))
8551                                 continue;
8552
8553                         if (is_default(*i) && !allparameters)
8554                                 continue;
8555
8556                         return &parm_table[(*i)++];
8557                 }
8558         } else {
8559                 struct service *pService = ServicePtrs[snum];
8560
8561                 for (; parm_table[*i].label; (*i)++) {
8562                         if (parm_table[*i].p_class == P_SEPARATOR)
8563                                 return &parm_table[(*i)++];
8564
8565                         if (parm_table[*i].p_class == P_LOCAL &&
8566                             parm_table[*i].ptr &&
8567                             (*parm_table[*i].label != '-') &&
8568                             ((*i) == 0 ||
8569                              (parm_table[*i].ptr !=
8570                               parm_table[(*i) - 1].ptr)))
8571                         {
8572                                 int pdiff =
8573                                         PTR_DIFF(parm_table[*i].ptr,
8574                                                  &sDefault);
8575
8576                                 if (allparameters ||
8577                                     !equal_parameter(parm_table[*i].type,
8578                                                      ((char *)pService) +
8579                                                      pdiff,
8580                                                      ((char *)&sDefault) +
8581                                                      pdiff))
8582                                 {
8583                                         return &parm_table[(*i)++];
8584                                 }
8585                         }
8586                 }
8587         }
8588
8589         return NULL;
8590 }
8591
8592
8593 #if 0
8594 /***************************************************************************
8595  Display the contents of a single copy structure.
8596 ***************************************************************************/
8597 static void dump_copy_map(bool *pcopymap)
8598 {
8599         int i;
8600         if (!pcopymap)
8601                 return;
8602
8603         printf("\n\tNon-Copied parameters:\n");
8604
8605         for (i = 0; parm_table[i].label; i++)
8606                 if (parm_table[i].p_class == P_LOCAL &&
8607                     parm_table[i].ptr && !pcopymap[i] &&
8608                     (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
8609                 {
8610                         printf("\t\t%s\n", parm_table[i].label);
8611                 }
8612 }
8613 #endif
8614
8615 /***************************************************************************
8616  Return TRUE if the passed service number is within range.
8617 ***************************************************************************/
8618
8619 bool lp_snum_ok(int iService)
8620 {
8621         return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
8622 }
8623
8624 /***************************************************************************
8625  Auto-load some home services.
8626 ***************************************************************************/
8627
8628 static void lp_add_auto_services(char *str)
8629 {
8630         char *s;
8631         char *p;
8632         int homes;
8633         char *saveptr;
8634
8635         if (!str)
8636                 return;
8637
8638         s = SMB_STRDUP(str);
8639         if (!s)
8640                 return;
8641
8642         homes = lp_servicenumber(HOMES_NAME);
8643
8644         for (p = strtok_r(s, LIST_SEP, &saveptr); p;
8645              p = strtok_r(NULL, LIST_SEP, &saveptr)) {
8646                 char *home;
8647
8648                 if (lp_servicenumber(p) >= 0)
8649                         continue;
8650
8651                 home = get_user_home_dir(talloc_tos(), p);
8652
8653                 if (home && home[0] && homes >= 0)
8654                         lp_add_home(p, homes, p, home);
8655
8656                 TALLOC_FREE(home);
8657         }
8658         SAFE_FREE(s);
8659 }
8660
8661 /***************************************************************************
8662  Auto-load one printer.
8663 ***************************************************************************/
8664
8665 void lp_add_one_printer(const char *name, const char *comment,
8666                         const char *location, void *pdata)
8667 {
8668         int printers = lp_servicenumber(PRINTERS_NAME);
8669         int i;
8670
8671         if (lp_servicenumber(name) < 0) {
8672                 lp_add_printer(name, printers);
8673                 if ((i = lp_servicenumber(name)) >= 0) {
8674                         string_set(&ServicePtrs[i]->comment, comment);
8675                         ServicePtrs[i]->autoloaded = True;
8676                 }
8677         }
8678 }
8679
8680 /***************************************************************************
8681  Have we loaded a services file yet?
8682 ***************************************************************************/
8683
8684 bool lp_loaded(void)
8685 {
8686         return (bLoaded);
8687 }
8688
8689 /***************************************************************************
8690  Unload unused services.
8691 ***************************************************************************/
8692
8693 void lp_killunused(struct smbd_server_connection *sconn,
8694                    bool (*snumused) (struct smbd_server_connection *, int))
8695 {
8696         int i;
8697         for (i = 0; i < iNumServices; i++) {
8698                 if (!VALID(i))
8699                         continue;
8700
8701                 /* don't kill autoloaded or usershare services */
8702                 if ( ServicePtrs[i]->autoloaded ||
8703                                 ServicePtrs[i]->usershare == USERSHARE_VALID) {
8704                         continue;
8705                 }
8706
8707                 if (!snumused || !snumused(sconn, i)) {
8708                         free_service_byindex(i);
8709                 }
8710         }
8711 }
8712
8713 /**
8714  * Kill all except autoloaded and usershare services - convenience wrapper
8715  */
8716 void lp_kill_all_services(void)
8717 {
8718         lp_killunused(NULL, NULL);
8719 }
8720
8721 /***************************************************************************
8722  Unload a service.
8723 ***************************************************************************/
8724
8725 void lp_killservice(int iServiceIn)
8726 {
8727         if (VALID(iServiceIn)) {
8728                 free_service_byindex(iServiceIn);
8729         }
8730 }
8731
8732 /***************************************************************************
8733  Save the curent values of all global and sDefault parameters into the 
8734  defaults union. This allows swat and testparm to show only the
8735  changed (ie. non-default) parameters.
8736 ***************************************************************************/
8737
8738 static void lp_save_defaults(void)
8739 {
8740         int i;
8741         for (i = 0; parm_table[i].label; i++) {
8742                 if (i > 0 && parm_table[i].ptr == parm_table[i - 1].ptr)
8743                         continue;
8744                 switch (parm_table[i].type) {
8745                         case P_LIST:
8746                                 parm_table[i].def.lvalue = str_list_copy(
8747                                         NULL, *(const char ***)parm_table[i].ptr);
8748                                 break;
8749                         case P_STRING:
8750                         case P_USTRING:
8751                                 if (parm_table[i].ptr) {
8752                                         parm_table[i].def.svalue = SMB_STRDUP(*(char **)parm_table[i].ptr);
8753                                 } else {
8754                                         parm_table[i].def.svalue = NULL;
8755                                 }
8756                                 break;
8757                         case P_BOOL:
8758                         case P_BOOLREV:
8759                                 parm_table[i].def.bvalue =
8760                                         *(bool *)parm_table[i].ptr;
8761                                 break;
8762                         case P_CHAR:
8763                                 parm_table[i].def.cvalue =
8764                                         *(char *)parm_table[i].ptr;
8765                                 break;
8766                         case P_INTEGER:
8767                         case P_OCTAL:
8768                         case P_ENUM:
8769                                 parm_table[i].def.ivalue =
8770                                         *(int *)parm_table[i].ptr;
8771                                 break;
8772                         case P_SEP:
8773                                 break;
8774                 }
8775         }
8776         defaults_saved = True;
8777 }
8778
8779 /***********************************************************
8780  If we should send plaintext/LANMAN passwords in the clinet
8781 ************************************************************/
8782
8783 static void set_allowed_client_auth(void)
8784 {
8785         if (Globals.bClientNTLMv2Auth) {
8786                 Globals.bClientLanManAuth = False;
8787         }
8788         if (!Globals.bClientLanManAuth) {
8789                 Globals.bClientPlaintextAuth = False;
8790         }
8791 }
8792
8793 /***************************************************************************
8794  JRA.
8795  The following code allows smbd to read a user defined share file.
8796  Yes, this is my intent. Yes, I'm comfortable with that...
8797
8798  THE FOLLOWING IS SECURITY CRITICAL CODE.
8799
8800  It washes your clothes, it cleans your house, it guards you while you sleep...
8801  Do not f%^k with it....
8802 ***************************************************************************/
8803
8804 #define MAX_USERSHARE_FILE_SIZE (10*1024)
8805
8806 /***************************************************************************
8807  Check allowed stat state of a usershare file.
8808  Ensure we print out who is dicking with us so the admin can
8809  get their sorry ass fired.
8810 ***************************************************************************/
8811
8812 static bool check_usershare_stat(const char *fname,
8813                                  const SMB_STRUCT_STAT *psbuf)
8814 {
8815         if (!S_ISREG(psbuf->st_ex_mode)) {
8816                 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
8817                         "not a regular file\n",
8818                         fname, (unsigned int)psbuf->st_ex_uid ));
8819                 return False;
8820         }
8821
8822         /* Ensure this doesn't have the other write bit set. */
8823         if (psbuf->st_ex_mode & S_IWOTH) {
8824                 DEBUG(0,("check_usershare_stat: file %s owned by uid %u allows "
8825                         "public write. Refusing to allow as a usershare file.\n",
8826                         fname, (unsigned int)psbuf->st_ex_uid ));
8827                 return False;
8828         }
8829
8830         /* Should be 10k or less. */
8831         if (psbuf->st_ex_size > MAX_USERSHARE_FILE_SIZE) {
8832                 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
8833                         "too large (%u) to be a user share file.\n",
8834                         fname, (unsigned int)psbuf->st_ex_uid,
8835                         (unsigned int)psbuf->st_ex_size ));
8836                 return False;
8837         }
8838
8839         return True;
8840 }
8841
8842 /***************************************************************************
8843  Parse the contents of a usershare file.
8844 ***************************************************************************/
8845
8846 enum usershare_err parse_usershare_file(TALLOC_CTX *ctx,
8847                         SMB_STRUCT_STAT *psbuf,
8848                         const char *servicename,
8849                         int snum,
8850                         char **lines,
8851                         int numlines,
8852                         char **pp_sharepath,
8853                         char **pp_comment,
8854                         char **pp_cp_servicename,
8855                         struct security_descriptor **ppsd,
8856                         bool *pallow_guest)
8857 {
8858         const char **prefixallowlist = lp_usershare_prefix_allow_list();
8859         const char **prefixdenylist = lp_usershare_prefix_deny_list();
8860         int us_vers;
8861         SMB_STRUCT_DIR *dp;
8862         SMB_STRUCT_STAT sbuf;
8863         char *sharepath = NULL;
8864         char *comment = NULL;
8865
8866         *pp_sharepath = NULL;
8867         *pp_comment = NULL;
8868
8869         *pallow_guest = False;
8870
8871         if (numlines < 4) {
8872                 return USERSHARE_MALFORMED_FILE;
8873         }
8874
8875         if (strcmp(lines[0], "#VERSION 1") == 0) {
8876                 us_vers = 1;
8877         } else if (strcmp(lines[0], "#VERSION 2") == 0) {
8878                 us_vers = 2;
8879                 if (numlines < 5) {
8880                         return USERSHARE_MALFORMED_FILE;
8881                 }
8882         } else {
8883                 return USERSHARE_BAD_VERSION;
8884         }
8885
8886         if (strncmp(lines[1], "path=", 5) != 0) {
8887                 return USERSHARE_MALFORMED_PATH;
8888         }
8889
8890         sharepath = talloc_strdup(ctx, &lines[1][5]);
8891         if (!sharepath) {
8892                 return USERSHARE_POSIX_ERR;
8893         }
8894         trim_string(sharepath, " ", " ");
8895
8896         if (strncmp(lines[2], "comment=", 8) != 0) {
8897                 return USERSHARE_MALFORMED_COMMENT_DEF;
8898         }
8899
8900         comment = talloc_strdup(ctx, &lines[2][8]);
8901         if (!comment) {
8902                 return USERSHARE_POSIX_ERR;
8903         }
8904         trim_string(comment, " ", " ");
8905         trim_char(comment, '"', '"');
8906
8907         if (strncmp(lines[3], "usershare_acl=", 14) != 0) {
8908                 return USERSHARE_MALFORMED_ACL_DEF;
8909         }
8910
8911         if (!parse_usershare_acl(ctx, &lines[3][14], ppsd)) {
8912                 return USERSHARE_ACL_ERR;
8913         }
8914
8915         if (us_vers == 2) {
8916                 if (strncmp(lines[4], "guest_ok=", 9) != 0) {
8917                         return USERSHARE_MALFORMED_ACL_DEF;
8918                 }
8919                 if (lines[4][9] == 'y') {
8920                         *pallow_guest = True;
8921                 }
8922
8923                 /* Backwards compatible extension to file version #2. */
8924                 if (numlines > 5) {
8925                         if (strncmp(lines[5], "sharename=", 10) != 0) {
8926                                 return USERSHARE_MALFORMED_SHARENAME_DEF;
8927                         }
8928                         if (!strequal(&lines[5][10], servicename)) {
8929                                 return USERSHARE_BAD_SHARENAME;
8930                         }
8931                         *pp_cp_servicename = talloc_strdup(ctx, &lines[5][10]);
8932                         if (!*pp_cp_servicename) {
8933                                 return USERSHARE_POSIX_ERR;
8934                         }
8935                 }
8936         }
8937
8938         if (*pp_cp_servicename == NULL) {
8939                 *pp_cp_servicename = talloc_strdup(ctx, servicename);
8940                 if (!*pp_cp_servicename) {
8941                         return USERSHARE_POSIX_ERR;
8942                 }
8943         }
8944
8945         if (snum != -1 && (strcmp(sharepath, ServicePtrs[snum]->szPath) == 0)) {
8946                 /* Path didn't change, no checks needed. */
8947                 *pp_sharepath = sharepath;
8948                 *pp_comment = comment;
8949                 return USERSHARE_OK;
8950         }
8951
8952         /* The path *must* be absolute. */
8953         if (sharepath[0] != '/') {
8954                 DEBUG(2,("parse_usershare_file: share %s: path %s is not an absolute path.\n",
8955                         servicename, sharepath));
8956                 return USERSHARE_PATH_NOT_ABSOLUTE;
8957         }
8958
8959         /* If there is a usershare prefix deny list ensure one of these paths
8960            doesn't match the start of the user given path. */
8961         if (prefixdenylist) {
8962                 int i;
8963                 for ( i=0; prefixdenylist[i]; i++ ) {
8964                         DEBUG(10,("parse_usershare_file: share %s : checking prefixdenylist[%d]='%s' against %s\n",
8965                                 servicename, i, prefixdenylist[i], sharepath ));
8966                         if (memcmp( sharepath, prefixdenylist[i], strlen(prefixdenylist[i])) == 0) {
8967                                 DEBUG(2,("parse_usershare_file: share %s path %s starts with one of the "
8968                                         "usershare prefix deny list entries.\n",
8969                                         servicename, sharepath));
8970                                 return USERSHARE_PATH_IS_DENIED;
8971                         }
8972                 }
8973         }
8974
8975         /* If there is a usershare prefix allow list ensure one of these paths
8976            does match the start of the user given path. */
8977
8978         if (prefixallowlist) {
8979                 int i;
8980                 for ( i=0; prefixallowlist[i]; i++ ) {
8981                         DEBUG(10,("parse_usershare_file: share %s checking prefixallowlist[%d]='%s' against %s\n",
8982                                 servicename, i, prefixallowlist[i], sharepath ));
8983                         if (memcmp( sharepath, prefixallowlist[i], strlen(prefixallowlist[i])) == 0) {
8984                                 break;
8985                         }
8986                 }
8987                 if (prefixallowlist[i] == NULL) {
8988                         DEBUG(2,("parse_usershare_file: share %s path %s doesn't start with one of the "
8989                                 "usershare prefix allow list entries.\n",
8990                                 servicename, sharepath));
8991                         return USERSHARE_PATH_NOT_ALLOWED;
8992                 }
8993         }
8994
8995         /* Ensure this is pointing to a directory. */
8996         dp = sys_opendir(sharepath);
8997
8998         if (!dp) {
8999                 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
9000                         servicename, sharepath));
9001                 return USERSHARE_PATH_NOT_DIRECTORY;
9002         }
9003
9004         /* Ensure the owner of the usershare file has permission to share
9005            this directory. */
9006
9007         if (sys_stat(sharepath, &sbuf, false) == -1) {
9008                 DEBUG(2,("parse_usershare_file: share %s : stat failed on path %s. %s\n",
9009                         servicename, sharepath, strerror(errno) ));
9010                 sys_closedir(dp);
9011                 return USERSHARE_POSIX_ERR;
9012         }
9013
9014         sys_closedir(dp);
9015
9016         if (!S_ISDIR(sbuf.st_ex_mode)) {
9017                 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
9018                         servicename, sharepath ));
9019                 return USERSHARE_PATH_NOT_DIRECTORY;
9020         }
9021
9022         /* Check if sharing is restricted to owner-only. */
9023         /* psbuf is the stat of the usershare definition file,
9024            sbuf is the stat of the target directory to be shared. */
9025
9026         if (lp_usershare_owner_only()) {
9027                 /* root can share anything. */
9028                 if ((psbuf->st_ex_uid != 0) && (sbuf.st_ex_uid != psbuf->st_ex_uid)) {
9029                         return USERSHARE_PATH_NOT_ALLOWED;
9030                 }
9031         }
9032
9033         *pp_sharepath = sharepath;
9034         *pp_comment = comment;
9035         return USERSHARE_OK;
9036 }
9037
9038 /***************************************************************************
9039  Deal with a usershare file.
9040  Returns:
9041         >= 0 - snum
9042         -1 - Bad name, invalid contents.
9043            - service name already existed and not a usershare, problem
9044             with permissions to share directory etc.
9045 ***************************************************************************/
9046
9047 static int process_usershare_file(const char *dir_name, const char *file_name, int snum_template)
9048 {
9049         SMB_STRUCT_STAT sbuf;
9050         SMB_STRUCT_STAT lsbuf;
9051         char *fname = NULL;
9052         char *sharepath = NULL;
9053         char *comment = NULL;
9054         char *cp_service_name = NULL;
9055         char **lines = NULL;
9056         int numlines = 0;
9057         int fd = -1;
9058         int iService = -1;
9059         TALLOC_CTX *ctx = talloc_stackframe();
9060         struct security_descriptor *psd = NULL;
9061         bool guest_ok = False;
9062         char *canon_name = NULL;
9063         bool added_service = false;
9064         int ret = -1;
9065
9066         /* Ensure share name doesn't contain invalid characters. */
9067         if (!validate_net_name(file_name, INVALID_SHARENAME_CHARS, strlen(file_name))) {
9068                 DEBUG(0,("process_usershare_file: share name %s contains "
9069                         "invalid characters (any of %s)\n",
9070                         file_name, INVALID_SHARENAME_CHARS ));
9071                 goto out;
9072         }
9073
9074         canon_name = canonicalize_servicename(ctx, file_name);
9075         if (!canon_name) {
9076                 goto out;
9077         }
9078
9079         fname = talloc_asprintf(ctx, "%s/%s", dir_name, file_name);
9080         if (!fname) {
9081                 goto out;
9082         }
9083
9084         /* Minimize the race condition by doing an lstat before we
9085            open and fstat. Ensure this isn't a symlink link. */
9086
9087         if (sys_lstat(fname, &lsbuf, false) != 0) {
9088                 DEBUG(0,("process_usershare_file: stat of %s failed. %s\n",
9089                         fname, strerror(errno) ));
9090                 goto out;
9091         }
9092
9093         /* This must be a regular file, not a symlink, directory or
9094            other strange filetype. */
9095         if (!check_usershare_stat(fname, &lsbuf)) {
9096                 goto out;
9097         }
9098
9099         {
9100                 TDB_DATA data = dbwrap_fetch_bystring(
9101                         ServiceHash, canon_name, canon_name);
9102
9103                 iService = -1;
9104
9105                 if ((data.dptr != NULL) && (data.dsize == sizeof(iService))) {
9106                         iService = *(int *)data.dptr;
9107                 }
9108         }
9109
9110         if (iService != -1 &&
9111             timespec_compare(&ServicePtrs[iService]->usershare_last_mod,
9112                              &lsbuf.st_ex_mtime) == 0) {
9113                 /* Nothing changed - Mark valid and return. */
9114                 DEBUG(10,("process_usershare_file: service %s not changed.\n",
9115                         canon_name ));
9116                 ServicePtrs[iService]->usershare = USERSHARE_VALID;
9117                 ret = iService;
9118                 goto out;
9119         }
9120
9121         /* Try and open the file read only - no symlinks allowed. */
9122 #ifdef O_NOFOLLOW
9123         fd = sys_open(fname, O_RDONLY|O_NOFOLLOW, 0);
9124 #else
9125         fd = sys_open(fname, O_RDONLY, 0);
9126 #endif
9127
9128         if (fd == -1) {
9129                 DEBUG(0,("process_usershare_file: unable to open %s. %s\n",
9130                         fname, strerror(errno) ));
9131                 goto out;
9132         }
9133
9134         /* Now fstat to be *SURE* it's a regular file. */
9135         if (sys_fstat(fd, &sbuf, false) != 0) {
9136                 close(fd);
9137                 DEBUG(0,("process_usershare_file: fstat of %s failed. %s\n",
9138                         fname, strerror(errno) ));
9139                 goto out;
9140         }
9141
9142         /* Is it the same dev/inode as was lstated ? */
9143         if (lsbuf.st_ex_dev != sbuf.st_ex_dev || lsbuf.st_ex_ino != sbuf.st_ex_ino) {
9144                 close(fd);
9145                 DEBUG(0,("process_usershare_file: fstat of %s is a different file from lstat. "
9146                         "Symlink spoofing going on ?\n", fname ));
9147                 goto out;
9148         }
9149
9150         /* This must be a regular file, not a symlink, directory or
9151            other strange filetype. */
9152         if (!check_usershare_stat(fname, &sbuf)) {
9153                 goto out;
9154         }
9155
9156         lines = fd_lines_load(fd, &numlines, MAX_USERSHARE_FILE_SIZE, NULL);
9157
9158         close(fd);
9159         if (lines == NULL) {
9160                 DEBUG(0,("process_usershare_file: loading file %s owned by %u failed.\n",
9161                         fname, (unsigned int)sbuf.st_ex_uid ));
9162                 goto out;
9163         }
9164
9165         if (parse_usershare_file(ctx, &sbuf, file_name,
9166                         iService, lines, numlines, &sharepath,
9167                         &comment, &cp_service_name,
9168                         &psd, &guest_ok) != USERSHARE_OK) {
9169                 goto out;
9170         }
9171
9172         /* Everything ok - add the service possibly using a template. */
9173         if (iService < 0) {
9174                 const struct service *sp = &sDefault;
9175                 if (snum_template != -1) {
9176                         sp = ServicePtrs[snum_template];
9177                 }
9178
9179                 if ((iService = add_a_service(sp, cp_service_name)) < 0) {
9180                         DEBUG(0, ("process_usershare_file: Failed to add "
9181                                 "new service %s\n", cp_service_name));
9182                         goto out;
9183                 }
9184
9185                 added_service = true;
9186
9187                 /* Read only is controlled by usershare ACL below. */
9188                 ServicePtrs[iService]->bRead_only = False;
9189         }
9190
9191         /* Write the ACL of the new/modified share. */
9192         if (!set_share_security(canon_name, psd)) {
9193                  DEBUG(0, ("process_usershare_file: Failed to set share "
9194                         "security for user share %s\n",
9195                         canon_name ));
9196                 goto out;
9197         }
9198
9199         /* If from a template it may be marked invalid. */
9200         ServicePtrs[iService]->valid = True;
9201
9202         /* Set the service as a valid usershare. */
9203         ServicePtrs[iService]->usershare = USERSHARE_VALID;
9204
9205         /* Set guest access. */
9206         if (lp_usershare_allow_guests()) {
9207                 ServicePtrs[iService]->bGuest_ok = guest_ok;
9208         }
9209
9210         /* And note when it was loaded. */
9211         ServicePtrs[iService]->usershare_last_mod = sbuf.st_ex_mtime;
9212         string_set(&ServicePtrs[iService]->szPath, sharepath);
9213         string_set(&ServicePtrs[iService]->comment, comment);
9214
9215         ret = iService;
9216
9217   out:
9218
9219         if (ret == -1 && iService != -1 && added_service) {
9220                 lp_remove_service(iService);
9221         }
9222
9223         TALLOC_FREE(lines);
9224         TALLOC_FREE(ctx);
9225         return ret;
9226 }
9227
9228 /***************************************************************************
9229  Checks if a usershare entry has been modified since last load.
9230 ***************************************************************************/
9231
9232 static bool usershare_exists(int iService, struct timespec *last_mod)
9233 {
9234         SMB_STRUCT_STAT lsbuf;
9235         const char *usersharepath = Globals.szUsersharePath;
9236         char *fname;
9237
9238         if (asprintf(&fname, "%s/%s",
9239                                 usersharepath,
9240                                 ServicePtrs[iService]->szService) < 0) {
9241                 return false;
9242         }
9243
9244         if (sys_lstat(fname, &lsbuf, false) != 0) {
9245                 SAFE_FREE(fname);
9246                 return false;
9247         }
9248
9249         if (!S_ISREG(lsbuf.st_ex_mode)) {
9250                 SAFE_FREE(fname);
9251                 return false;
9252         }
9253
9254         SAFE_FREE(fname);
9255         *last_mod = lsbuf.st_ex_mtime;
9256         return true;
9257 }
9258
9259 /***************************************************************************
9260  Load a usershare service by name. Returns a valid servicenumber or -1.
9261 ***************************************************************************/
9262
9263 int load_usershare_service(const char *servicename)
9264 {
9265         SMB_STRUCT_STAT sbuf;
9266         const char *usersharepath = Globals.szUsersharePath;
9267         int max_user_shares = Globals.iUsershareMaxShares;
9268         int snum_template = -1;
9269
9270         if (*usersharepath == 0 ||  max_user_shares == 0) {
9271                 return -1;
9272         }
9273
9274         if (sys_stat(usersharepath, &sbuf, false) != 0) {
9275                 DEBUG(0,("load_usershare_service: stat of %s failed. %s\n",
9276                         usersharepath, strerror(errno) ));
9277                 return -1;
9278         }
9279
9280         if (!S_ISDIR(sbuf.st_ex_mode)) {
9281                 DEBUG(0,("load_usershare_service: %s is not a directory.\n",
9282                         usersharepath ));
9283                 return -1;
9284         }
9285
9286         /*
9287          * This directory must be owned by root, and have the 't' bit set.
9288          * It also must not be writable by "other".
9289          */
9290
9291 #ifdef S_ISVTX
9292         if (sbuf.st_ex_uid != 0 || !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
9293 #else
9294         if (sbuf.st_ex_uid != 0 || (sbuf.st_ex_mode & S_IWOTH)) {
9295 #endif
9296                 DEBUG(0,("load_usershare_service: directory %s is not owned by root "
9297                         "or does not have the sticky bit 't' set or is writable by anyone.\n",
9298                         usersharepath ));
9299                 return -1;
9300         }
9301
9302         /* Ensure the template share exists if it's set. */
9303         if (Globals.szUsershareTemplateShare[0]) {
9304                 /* We can't use lp_servicenumber here as we are recommending that
9305                    template shares have -valid=False set. */
9306                 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
9307                         if (ServicePtrs[snum_template]->szService &&
9308                                         strequal(ServicePtrs[snum_template]->szService,
9309                                                 Globals.szUsershareTemplateShare)) {
9310                                 break;
9311                         }
9312                 }
9313
9314                 if (snum_template == -1) {
9315                         DEBUG(0,("load_usershare_service: usershare template share %s "
9316                                 "does not exist.\n",
9317                                 Globals.szUsershareTemplateShare ));
9318                         return -1;
9319                 }
9320         }
9321
9322         return process_usershare_file(usersharepath, servicename, snum_template);
9323 }
9324
9325 /***************************************************************************
9326  Load all user defined shares from the user share directory.
9327  We only do this if we're enumerating the share list.
9328  This is the function that can delete usershares that have
9329  been removed.
9330 ***************************************************************************/
9331
9332 int load_usershare_shares(struct smbd_server_connection *sconn)
9333 {
9334         SMB_STRUCT_DIR *dp;
9335         SMB_STRUCT_STAT sbuf;
9336         SMB_STRUCT_DIRENT *de;
9337         int num_usershares = 0;
9338         int max_user_shares = Globals.iUsershareMaxShares;
9339         unsigned int num_dir_entries, num_bad_dir_entries, num_tmp_dir_entries;
9340         unsigned int allowed_bad_entries = ((2*max_user_shares)/10);
9341         unsigned int allowed_tmp_entries = ((2*max_user_shares)/10);
9342         int iService;
9343         int snum_template = -1;
9344         const char *usersharepath = Globals.szUsersharePath;
9345         int ret = lp_numservices();
9346
9347         if (max_user_shares == 0 || *usersharepath == '\0') {
9348                 return lp_numservices();
9349         }
9350
9351         if (sys_stat(usersharepath, &sbuf, false) != 0) {
9352                 DEBUG(0,("load_usershare_shares: stat of %s failed. %s\n",
9353                         usersharepath, strerror(errno) ));
9354                 return ret;
9355         }
9356
9357         /*
9358          * This directory must be owned by root, and have the 't' bit set.
9359          * It also must not be writable by "other".
9360          */
9361
9362 #ifdef S_ISVTX
9363         if (sbuf.st_ex_uid != 0 || !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
9364 #else
9365         if (sbuf.st_ex_uid != 0 || (sbuf.st_ex_mode & S_IWOTH)) {
9366 #endif
9367                 DEBUG(0,("load_usershare_shares: directory %s is not owned by root "
9368                         "or does not have the sticky bit 't' set or is writable by anyone.\n",
9369                         usersharepath ));
9370                 return ret;
9371         }
9372
9373         /* Ensure the template share exists if it's set. */
9374         if (Globals.szUsershareTemplateShare[0]) {
9375                 /* We can't use lp_servicenumber here as we are recommending that
9376                    template shares have -valid=False set. */
9377                 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
9378                         if (ServicePtrs[snum_template]->szService &&
9379                                         strequal(ServicePtrs[snum_template]->szService,
9380                                                 Globals.szUsershareTemplateShare)) {
9381                                 break;
9382                         }
9383                 }
9384
9385                 if (snum_template == -1) {
9386                         DEBUG(0,("load_usershare_shares: usershare template share %s "
9387                                 "does not exist.\n",
9388                                 Globals.szUsershareTemplateShare ));
9389                         return ret;
9390                 }
9391         }
9392
9393         /* Mark all existing usershares as pending delete. */
9394         for (iService = iNumServices - 1; iService >= 0; iService--) {
9395                 if (VALID(iService) && ServicePtrs[iService]->usershare) {
9396                         ServicePtrs[iService]->usershare = USERSHARE_PENDING_DELETE;
9397                 }
9398         }
9399
9400         dp = sys_opendir(usersharepath);
9401         if (!dp) {
9402                 DEBUG(0,("load_usershare_shares:: failed to open directory %s. %s\n",
9403                         usersharepath, strerror(errno) ));
9404                 return ret;
9405         }
9406
9407         for (num_dir_entries = 0, num_bad_dir_entries = 0, num_tmp_dir_entries = 0;
9408                         (de = sys_readdir(dp));
9409                         num_dir_entries++ ) {
9410                 int r;
9411                 const char *n = de->d_name;
9412
9413                 /* Ignore . and .. */
9414                 if (*n == '.') {
9415                         if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) {
9416                                 continue;
9417                         }
9418                 }
9419
9420                 if (n[0] == ':') {
9421                         /* Temporary file used when creating a share. */
9422                         num_tmp_dir_entries++;
9423                 }
9424
9425                 /* Allow 20% tmp entries. */
9426                 if (num_tmp_dir_entries > allowed_tmp_entries) {
9427                         DEBUG(0,("load_usershare_shares: too many temp entries (%u) "
9428                                 "in directory %s\n",
9429                                 num_tmp_dir_entries, usersharepath));
9430                         break;
9431                 }
9432
9433                 r = process_usershare_file(usersharepath, n, snum_template);
9434                 if (r == 0) {
9435                         /* Update the services count. */
9436                         num_usershares++;
9437                         if (num_usershares >= max_user_shares) {
9438                                 DEBUG(0,("load_usershare_shares: max user shares reached "
9439                                         "on file %s in directory %s\n",
9440                                         n, usersharepath ));
9441                                 break;
9442                         }
9443                 } else if (r == -1) {
9444                         num_bad_dir_entries++;
9445                 }
9446
9447                 /* Allow 20% bad entries. */
9448                 if (num_bad_dir_entries > allowed_bad_entries) {
9449                         DEBUG(0,("load_usershare_shares: too many bad entries (%u) "
9450                                 "in directory %s\n",
9451                                 num_bad_dir_entries, usersharepath));
9452                         break;
9453                 }
9454
9455                 /* Allow 20% bad entries. */
9456                 if (num_dir_entries > max_user_shares + allowed_bad_entries) {
9457                         DEBUG(0,("load_usershare_shares: too many total entries (%u) "
9458                         "in directory %s\n",
9459                         num_dir_entries, usersharepath));
9460                         break;
9461                 }
9462         }
9463
9464         sys_closedir(dp);
9465
9466         /* Sweep through and delete any non-refreshed usershares that are
9467            not currently in use. */
9468         for (iService = iNumServices - 1; iService >= 0; iService--) {
9469                 if (VALID(iService) && (ServicePtrs[iService]->usershare == USERSHARE_PENDING_DELETE)) {
9470                         if (conn_snum_used(sconn, iService)) {
9471                                 continue;
9472                         }
9473                         /* Remove from the share ACL db. */
9474                         DEBUG(10,("load_usershare_shares: Removing deleted usershare %s\n",
9475                                 lp_servicename(iService) ));
9476                         delete_share_security(lp_servicename(iService));
9477                         free_service_byindex(iService);
9478                 }
9479         }
9480
9481         return lp_numservices();
9482 }
9483
9484 /********************************************************
9485  Destroy global resources allocated in this file
9486 ********************************************************/
9487
9488 void gfree_loadparm(void)
9489 {
9490         int i;
9491
9492         free_file_list();
9493
9494         /* Free resources allocated to services */
9495
9496         for ( i = 0; i < iNumServices; i++ ) {
9497                 if ( VALID(i) ) {
9498                         free_service_byindex(i);
9499                 }
9500         }
9501
9502         SAFE_FREE( ServicePtrs );
9503         iNumServices = 0;
9504
9505         /* Now release all resources allocated to global
9506            parameters and the default service */
9507
9508         free_global_parameters();
9509 }
9510
9511
9512 /***************************************************************************
9513  Allow client apps to specify that they are a client
9514 ***************************************************************************/
9515 void lp_set_in_client(bool b)
9516 {
9517     in_client = b;
9518 }
9519
9520
9521 /***************************************************************************
9522  Determine if we're running in a client app
9523 ***************************************************************************/
9524 bool lp_is_in_client(void)
9525 {
9526     return in_client;
9527 }
9528
9529 /***************************************************************************
9530  Load the services array from the services file. Return True on success, 
9531  False on failure.
9532 ***************************************************************************/
9533
9534 static bool lp_load_ex(const char *pszFname,
9535                        bool global_only,
9536                        bool save_defaults,
9537                        bool add_ipc,
9538                        bool initialize_globals,
9539                        bool allow_include_registry,
9540                        bool allow_registry_shares)
9541 {
9542         char *n2 = NULL;
9543         bool bRetval;
9544
9545         bRetval = False;
9546
9547         DEBUG(3, ("lp_load_ex: refreshing parameters\n"));
9548
9549         bInGlobalSection = True;
9550         bGlobalOnly = global_only;
9551         bAllowIncludeRegistry = allow_include_registry;
9552
9553         init_globals(initialize_globals);
9554
9555         free_file_list();
9556
9557         if (save_defaults) {
9558                 init_locals();
9559                 lp_save_defaults();
9560         }
9561
9562         free_param_opts(&Globals.param_opt);
9563
9564         lp_do_parameter(-1, "idmap config * : backend", Globals.szIdmapBackend);
9565
9566         /* We get sections first, so have to start 'behind' to make up */
9567         iServiceIndex = -1;
9568
9569         if (lp_config_backend_is_file()) {
9570                 n2 = talloc_sub_basic(talloc_tos(), get_current_username(),
9571                                         current_user_info.domain,
9572                                         pszFname);
9573                 if (!n2) {
9574                         smb_panic("lp_load_ex: out of memory");
9575                 }
9576
9577                 add_to_file_list(pszFname, n2);
9578
9579                 bRetval = pm_process(n2, do_section, do_parameter, NULL);
9580                 TALLOC_FREE(n2);
9581
9582                 /* finish up the last section */
9583                 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
9584                 if (bRetval) {
9585                         if (iServiceIndex >= 0) {
9586                                 bRetval = service_ok(iServiceIndex);
9587                         }
9588                 }
9589
9590                 if (lp_config_backend_is_registry()) {
9591                         /* config backend changed to registry in config file */
9592                         /*
9593                          * We need to use this extra global variable here to
9594                          * survive restart: init_globals uses this as a default
9595                          * for ConfigBackend. Otherwise, init_globals would
9596                          *  send us into an endless loop here.
9597                          */
9598                         config_backend = CONFIG_BACKEND_REGISTRY;
9599                         /* start over */
9600                         DEBUG(1, ("lp_load_ex: changing to config backend "
9601                                   "registry\n"));
9602                         init_globals(true);
9603                         lp_kill_all_services();
9604                         return lp_load_ex(pszFname, global_only, save_defaults,
9605                                           add_ipc, initialize_globals,
9606                                           allow_include_registry,
9607                                           allow_registry_shares);
9608                 }
9609         } else if (lp_config_backend_is_registry()) {
9610                 bRetval = process_registry_globals();
9611         } else {
9612                 DEBUG(0, ("Illegal config  backend given: %d\n",
9613                           lp_config_backend()));
9614                 bRetval = false;
9615         }
9616
9617         if (bRetval && lp_registry_shares() && allow_registry_shares) {
9618                 bRetval = process_registry_shares();
9619         }
9620
9621         lp_add_auto_services(lp_auto_services());
9622
9623         if (add_ipc) {
9624                 /* When 'restrict anonymous = 2' guest connections to ipc$
9625                    are denied */
9626                 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
9627                 if ( lp_enable_asu_support() ) {
9628                         lp_add_ipc("ADMIN$", false);
9629                 }
9630         }
9631
9632         set_server_role();
9633         set_default_server_announce_type();
9634         set_allowed_client_auth();
9635
9636         if (lp_security() == SEC_SHARE) {
9637                 DEBUG(1, ("WARNING: The security=share option is deprecated\n"));
9638         } else if (lp_security() == SEC_SERVER) {
9639                 DEBUG(1, ("WARNING: The security=server option is deprecated\n"));
9640         }
9641
9642         if (lp_security() == SEC_ADS && strchr(lp_passwordserver(), ':')) {
9643                 DEBUG(1, ("WARNING: The optional ':port' in password server = %s is deprecated\n",
9644                           lp_passwordserver()));
9645         }
9646
9647         bLoaded = True;
9648
9649         /* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */
9650         /* if bWINSsupport is true and we are in the client            */
9651         if (lp_is_in_client() && Globals.bWINSsupport) {
9652                 lp_do_parameter(GLOBAL_SECTION_SNUM, "wins server", "127.0.0.1");
9653         }
9654
9655         init_iconv();
9656
9657         fault_configure(smb_panic_s3);
9658
9659         bAllowIncludeRegistry = true;
9660
9661         return (bRetval);
9662 }
9663
9664 bool lp_load(const char *pszFname,
9665              bool global_only,
9666              bool save_defaults,
9667              bool add_ipc,
9668              bool initialize_globals)
9669 {
9670         return lp_load_ex(pszFname,
9671                           global_only,
9672                           save_defaults,
9673                           add_ipc,
9674                           initialize_globals,
9675                           true,   /* allow_include_registry */
9676                           false); /* allow_registry_shares*/
9677 }
9678
9679 bool lp_load_initial_only(const char *pszFname)
9680 {
9681         return lp_load_ex(pszFname,
9682                           true,   /* global only */
9683                           false,  /* save_defaults */
9684                           false,  /* add_ipc */
9685                           true,   /* initialize_globals */
9686                           false,  /* allow_include_registry */
9687                           false); /* allow_registry_shares*/
9688 }
9689
9690 bool lp_load_with_registry_shares(const char *pszFname,
9691                                   bool global_only,
9692                                   bool save_defaults,
9693                                   bool add_ipc,
9694                                   bool initialize_globals)
9695 {
9696         return lp_load_ex(pszFname,
9697                           global_only,
9698                           save_defaults,
9699                           add_ipc,
9700                           initialize_globals,
9701                           true,  /* allow_include_registry */
9702                           true); /* allow_registry_shares*/
9703 }
9704
9705 /***************************************************************************
9706  Return the max number of services.
9707 ***************************************************************************/
9708
9709 int lp_numservices(void)
9710 {
9711         return (iNumServices);
9712 }
9713
9714 /***************************************************************************
9715 Display the contents of the services array in human-readable form.
9716 ***************************************************************************/
9717
9718 void lp_dump(FILE *f, bool show_defaults, int maxtoprint)
9719 {
9720         int iService;
9721
9722         if (show_defaults)
9723                 defaults_saved = False;
9724
9725         dump_globals(f);
9726
9727         dump_a_service(&sDefault, f);
9728
9729         for (iService = 0; iService < maxtoprint; iService++) {
9730                 fprintf(f,"\n");
9731                 lp_dump_one(f, show_defaults, iService);
9732         }
9733 }
9734
9735 /***************************************************************************
9736 Display the contents of one service in human-readable form.
9737 ***************************************************************************/
9738
9739 void lp_dump_one(FILE * f, bool show_defaults, int snum)
9740 {
9741         if (VALID(snum)) {
9742                 if (ServicePtrs[snum]->szService[0] == '\0')
9743                         return;
9744                 dump_a_service(ServicePtrs[snum], f);
9745         }
9746 }
9747
9748 /***************************************************************************
9749 Return the number of the service with the given name, or -1 if it doesn't
9750 exist. Note that this is a DIFFERENT ANIMAL from the internal function
9751 getservicebyname()! This works ONLY if all services have been loaded, and
9752 does not copy the found service.
9753 ***************************************************************************/
9754
9755 int lp_servicenumber(const char *pszServiceName)
9756 {
9757         int iService;
9758         fstring serviceName;
9759
9760         if (!pszServiceName) {
9761                 return GLOBAL_SECTION_SNUM;
9762         }
9763
9764         for (iService = iNumServices - 1; iService >= 0; iService--) {
9765                 if (VALID(iService) && ServicePtrs[iService]->szService) {
9766                         /*
9767                          * The substitution here is used to support %U is
9768                          * service names
9769                          */
9770                         fstrcpy(serviceName, ServicePtrs[iService]->szService);
9771                         standard_sub_basic(get_current_username(),
9772                                            current_user_info.domain,
9773                                            serviceName,sizeof(serviceName));
9774                         if (strequal(serviceName, pszServiceName)) {
9775                                 break;
9776                         }
9777                 }
9778         }
9779
9780         if (iService >= 0 && ServicePtrs[iService]->usershare == USERSHARE_VALID) {
9781                 struct timespec last_mod;
9782
9783                 if (!usershare_exists(iService, &last_mod)) {
9784                         /* Remove the share security tdb entry for it. */
9785                         delete_share_security(lp_servicename(iService));
9786                         /* Remove it from the array. */
9787                         free_service_byindex(iService);
9788                         /* Doesn't exist anymore. */
9789                         return GLOBAL_SECTION_SNUM;
9790                 }
9791
9792                 /* Has it been modified ? If so delete and reload. */
9793                 if (timespec_compare(&ServicePtrs[iService]->usershare_last_mod,
9794                                      &last_mod) < 0) {
9795                         /* Remove it from the array. */
9796                         free_service_byindex(iService);
9797                         /* and now reload it. */
9798                         iService = load_usershare_service(pszServiceName);
9799                 }
9800         }
9801
9802         if (iService < 0) {
9803                 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
9804                 return GLOBAL_SECTION_SNUM;
9805         }
9806
9807         return (iService);
9808 }
9809
9810 bool share_defined(const char *service_name)
9811 {
9812         return (lp_servicenumber(service_name) != -1);
9813 }
9814
9815 /*******************************************************************
9816  A useful volume label function. 
9817 ********************************************************************/
9818
9819 const char *volume_label(int snum)
9820 {
9821         char *ret;
9822         const char *label = lp_volume(snum);
9823         if (!*label) {
9824                 label = lp_servicename(snum);
9825         }
9826
9827         /* This returns a 33 byte guarenteed null terminated string. */
9828         ret = talloc_strndup(talloc_tos(), label, 32);
9829         if (!ret) {
9830                 return "";
9831         }               
9832         return ret;
9833 }
9834
9835 /*******************************************************************
9836  Set the server type we will announce as via nmbd.
9837 ********************************************************************/
9838
9839 static void set_default_server_announce_type(void)
9840 {
9841         default_server_announce = 0;
9842         default_server_announce |= SV_TYPE_WORKSTATION;
9843         default_server_announce |= SV_TYPE_SERVER;
9844         default_server_announce |= SV_TYPE_SERVER_UNIX;
9845
9846         /* note that the flag should be set only if we have a 
9847            printer service but nmbd doesn't actually load the 
9848            services so we can't tell   --jerry */
9849
9850         default_server_announce |= SV_TYPE_PRINTQ_SERVER;
9851
9852         switch (lp_announce_as()) {
9853                 case ANNOUNCE_AS_NT_SERVER:
9854                         default_server_announce |= SV_TYPE_SERVER_NT;
9855                         /* fall through... */
9856                 case ANNOUNCE_AS_NT_WORKSTATION:
9857                         default_server_announce |= SV_TYPE_NT;
9858                         break;
9859                 case ANNOUNCE_AS_WIN95:
9860                         default_server_announce |= SV_TYPE_WIN95_PLUS;
9861                         break;
9862                 case ANNOUNCE_AS_WFW:
9863                         default_server_announce |= SV_TYPE_WFW;
9864                         break;
9865                 default:
9866                         break;
9867         }
9868
9869         switch (lp_server_role()) {
9870                 case ROLE_DOMAIN_MEMBER:
9871                         default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
9872                         break;
9873                 case ROLE_DOMAIN_PDC:
9874                         default_server_announce |= SV_TYPE_DOMAIN_CTRL;
9875                         break;
9876                 case ROLE_DOMAIN_BDC:
9877                         default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
9878                         break;
9879                 case ROLE_STANDALONE:
9880                 default:
9881                         break;
9882         }
9883         if (lp_time_server())
9884                 default_server_announce |= SV_TYPE_TIME_SOURCE;
9885
9886         if (lp_host_msdfs())
9887                 default_server_announce |= SV_TYPE_DFS_SERVER;
9888 }
9889
9890 /***********************************************************
9891  If we are PDC then prefer us as DMB
9892 ************************************************************/
9893
9894 bool lp_domain_master(void)
9895 {
9896         if (Globals.iDomainMaster == Auto)
9897                 return (lp_server_role() == ROLE_DOMAIN_PDC);
9898
9899         return (bool)Globals.iDomainMaster;
9900 }
9901
9902 /***********************************************************
9903  If we are PDC then prefer us as DMB
9904 ************************************************************/
9905
9906 bool lp_domain_master_true_or_auto(void)
9907 {
9908         if (Globals.iDomainMaster) /* auto or yes */
9909                 return true;
9910
9911         return false;
9912 }
9913
9914 /***********************************************************
9915  If we are DMB then prefer us as LMB
9916 ************************************************************/
9917
9918 bool lp_preferred_master(void)
9919 {
9920         if (Globals.iPreferredMaster == Auto)
9921                 return (lp_local_master() && lp_domain_master());
9922
9923         return (bool)Globals.iPreferredMaster;
9924 }
9925
9926 /*******************************************************************
9927  Remove a service.
9928 ********************************************************************/
9929
9930 void lp_remove_service(int snum)
9931 {
9932         ServicePtrs[snum]->valid = False;
9933         invalid_services[num_invalid_services++] = snum;
9934 }
9935
9936 /*******************************************************************
9937  Copy a service.
9938 ********************************************************************/
9939
9940 void lp_copy_service(int snum, const char *new_name)
9941 {
9942         do_section(new_name, NULL);
9943         if (snum >= 0) {
9944                 snum = lp_servicenumber(new_name);
9945                 if (snum >= 0)
9946                         lp_do_parameter(snum, "copy", lp_servicename(snum));
9947         }
9948 }
9949
9950
9951 /*******************************************************************
9952  Get the default server type we will announce as via nmbd.
9953 ********************************************************************/
9954
9955 int lp_default_server_announce(void)
9956 {
9957         return default_server_announce;
9958 }
9959
9960 /*******************************************************************
9961  Split the announce version into major and minor numbers.
9962 ********************************************************************/
9963
9964 int lp_major_announce_version(void)
9965 {
9966         static bool got_major = False;
9967         static int major_version = DEFAULT_MAJOR_VERSION;
9968         char *vers;
9969         char *p;
9970
9971         if (got_major)
9972                 return major_version;
9973
9974         got_major = True;
9975         if ((vers = lp_announce_version()) == NULL)
9976                 return major_version;
9977
9978         if ((p = strchr_m(vers, '.')) == 0)
9979                 return major_version;
9980
9981         *p = '\0';
9982         major_version = atoi(vers);
9983         return major_version;
9984 }
9985
9986 int lp_minor_announce_version(void)
9987 {
9988         static bool got_minor = False;
9989         static int minor_version = DEFAULT_MINOR_VERSION;
9990         char *vers;
9991         char *p;
9992
9993         if (got_minor)
9994                 return minor_version;
9995
9996         got_minor = True;
9997         if ((vers = lp_announce_version()) == NULL)
9998                 return minor_version;
9999
10000         if ((p = strchr_m(vers, '.')) == 0)
10001                 return minor_version;
10002
10003         p++;
10004         minor_version = atoi(p);
10005         return minor_version;
10006 }
10007
10008 /***********************************************************
10009  Set the global name resolution order (used in smbclient).
10010 ************************************************************/
10011
10012 void lp_set_name_resolve_order(const char *new_order)
10013 {
10014         string_set(&Globals.szNameResolveOrder, new_order);
10015 }
10016
10017 const char *lp_printername(int snum)
10018 {
10019         const char *ret = _lp_printername(snum);
10020         if (ret == NULL || (ret != NULL && *ret == '\0'))
10021                 ret = lp_const_servicename(snum);
10022
10023         return ret;
10024 }
10025
10026
10027 /***********************************************************
10028  Allow daemons such as winbindd to fix their logfile name.
10029 ************************************************************/
10030
10031 void lp_set_logfile(const char *name)
10032 {
10033         string_set(&Globals.szLogFile, name);
10034         debug_set_logfile(name);
10035 }
10036
10037 /*******************************************************************
10038  Return the max print jobs per queue.
10039 ********************************************************************/
10040
10041 int lp_maxprintjobs(int snum)
10042 {
10043         int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
10044         if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
10045                 maxjobs = PRINT_MAX_JOBID - 1;
10046
10047         return maxjobs;
10048 }
10049
10050 const char *lp_printcapname(void)
10051 {
10052         if ((Globals.szPrintcapname != NULL) &&
10053             (Globals.szPrintcapname[0] != '\0'))
10054                 return Globals.szPrintcapname;
10055
10056         if (sDefault.iPrinting == PRINT_CUPS) {
10057 #ifdef HAVE_CUPS
10058                 return "cups";
10059 #else
10060                 return "lpstat";
10061 #endif
10062         }
10063
10064         if (sDefault.iPrinting == PRINT_BSD)
10065                 return "/etc/printcap";
10066
10067         return PRINTCAP_NAME;
10068 }
10069
10070 static uint32 spoolss_state;
10071
10072 bool lp_disable_spoolss( void )
10073 {
10074         if ( spoolss_state == SVCCTL_STATE_UNKNOWN )
10075                 spoolss_state = _lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
10076
10077         return spoolss_state == SVCCTL_STOPPED ? True : False;
10078 }
10079
10080 void lp_set_spoolss_state( uint32 state )
10081 {
10082         SMB_ASSERT( (state == SVCCTL_STOPPED) || (state == SVCCTL_RUNNING) );
10083
10084         spoolss_state = state;
10085 }
10086
10087 uint32 lp_get_spoolss_state( void )
10088 {
10089         return lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
10090 }
10091
10092 /*******************************************************************
10093  Ensure we don't use sendfile if server smb signing is active.
10094 ********************************************************************/
10095
10096 bool lp_use_sendfile(int snum, struct smb_signing_state *signing_state)
10097 {
10098         bool sign_active = false;
10099
10100         /* Using sendfile blows the brains out of any DOS or Win9x TCP stack... JRA. */
10101         if (get_Protocol() < PROTOCOL_NT1) {
10102                 return false;
10103         }
10104         if (signing_state) {
10105                 sign_active = smb_signing_is_active(signing_state);
10106         }
10107         return (_lp_use_sendfile(snum) &&
10108                         (get_remote_arch() != RA_WIN95) &&
10109                         !sign_active);
10110 }
10111
10112 /*******************************************************************
10113  Turn off sendfile if we find the underlying OS doesn't support it.
10114 ********************************************************************/
10115
10116 void set_use_sendfile(int snum, bool val)
10117 {
10118         if (LP_SNUM_OK(snum))
10119                 ServicePtrs[snum]->bUseSendfile = val;
10120         else
10121                 sDefault.bUseSendfile = val;
10122 }
10123
10124 /*******************************************************************
10125  Turn off storing DOS attributes if this share doesn't support it.
10126 ********************************************************************/
10127
10128 void set_store_dos_attributes(int snum, bool val)
10129 {
10130         if (!LP_SNUM_OK(snum))
10131                 return;
10132         ServicePtrs[(snum)]->bStoreDosAttributes = val;
10133 }
10134
10135 void lp_set_mangling_method(const char *new_method)
10136 {
10137         string_set(&Globals.szManglingMethod, new_method);
10138 }
10139
10140 /*******************************************************************
10141  Global state for POSIX pathname processing.
10142 ********************************************************************/
10143
10144 static bool posix_pathnames;
10145
10146 bool lp_posix_pathnames(void)
10147 {
10148         return posix_pathnames;
10149 }
10150
10151 /*******************************************************************
10152  Change everything needed to ensure POSIX pathname processing (currently
10153  not much).
10154 ********************************************************************/
10155
10156 void lp_set_posix_pathnames(void)
10157 {
10158         posix_pathnames = True;
10159 }
10160
10161 /*******************************************************************
10162  Global state for POSIX lock processing - CIFS unix extensions.
10163 ********************************************************************/
10164
10165 bool posix_default_lock_was_set;
10166 static enum brl_flavour posix_cifsx_locktype; /* By default 0 == WINDOWS_LOCK */
10167
10168 enum brl_flavour lp_posix_cifsu_locktype(files_struct *fsp)
10169 {
10170         if (posix_default_lock_was_set) {
10171                 return posix_cifsx_locktype;
10172         } else {
10173                 return fsp->posix_open ? POSIX_LOCK : WINDOWS_LOCK;
10174         }
10175 }
10176
10177 /*******************************************************************
10178 ********************************************************************/
10179
10180 void lp_set_posix_default_cifsx_readwrite_locktype(enum brl_flavour val)
10181 {
10182         posix_default_lock_was_set = True;
10183         posix_cifsx_locktype = val;
10184 }
10185
10186 int lp_min_receive_file_size(void)
10187 {
10188         if (Globals.iminreceivefile < 0) {
10189                 return 0;
10190         }
10191         return MIN(Globals.iminreceivefile, BUFFER_SIZE);
10192 }
10193
10194 /*******************************************************************
10195  If socket address is an empty character string, it is necessary to 
10196  define it as "0.0.0.0". 
10197 ********************************************************************/
10198
10199 const char *lp_socket_address(void)
10200 {
10201         char *sock_addr = Globals.szSocketAddress;
10202
10203         if (sock_addr[0] == '\0'){
10204                 string_set(&Globals.szSocketAddress, "0.0.0.0");
10205         }
10206         return  Globals.szSocketAddress;
10207 }
10208
10209 void lp_set_passdb_backend(const char *backend)
10210 {
10211         string_set(&Globals.szPassdbBackend, backend);
10212 }
10213
10214 /*******************************************************************
10215  Safe wide links checks.
10216  This helper function always verify the validity of wide links,
10217  even after a configuration file reload.
10218 ********************************************************************/
10219
10220 static bool lp_widelinks_internal(int snum)
10221 {
10222         return (bool)(LP_SNUM_OK(snum)? ServicePtrs[(snum)]->bWidelinks :
10223                         sDefault.bWidelinks);
10224 }
10225
10226 void widelinks_warning(int snum)
10227 {
10228         if (lp_unix_extensions() && lp_widelinks_internal(snum)) {
10229                 DEBUG(0,("Share '%s' has wide links and unix extensions enabled. "
10230                         "These parameters are incompatible. "
10231                         "Wide links will be disabled for this share.\n",
10232                         lp_servicename(snum) ));
10233         }
10234 }
10235
10236 bool lp_widelinks(int snum)
10237 {
10238         /* wide links is always incompatible with unix extensions */
10239         if (lp_unix_extensions()) {
10240                 return false;
10241         }
10242
10243         return lp_widelinks_internal(snum);
10244 }
10245
10246 bool lp_writeraw(void)
10247 {
10248         if (lp_async_smb_echo_handler()) {
10249                 return false;
10250         }
10251         return _lp_writeraw();
10252 }
10253
10254 bool lp_readraw(void)
10255 {
10256         if (lp_async_smb_echo_handler()) {
10257                 return false;
10258         }
10259         return _lp_readraw();
10260 }