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