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