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