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