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