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