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