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