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