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