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