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