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