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