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