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