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