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