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