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