loadparm: make lo_load_initial() only skip registry include.
[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 static struct smbconf_ctx *conf_ctx = NULL;
84
85 #define CONFIG_BACKEND_FILE 0
86 #define CONFIG_BACKEND_REGISTRY 1
87
88 static int config_backend = CONFIG_BACKEND_FILE;
89
90 /* some helpful bits */
91 #define LP_SNUM_OK(i) (((i) >= 0) && ((i) < iNumServices) && (ServicePtrs != NULL) && ServicePtrs[(i)]->valid)
92 #define VALID(i) (ServicePtrs != NULL && ServicePtrs[i]->valid)
93
94 #define USERSHARE_VALID 1
95 #define USERSHARE_PENDING_DELETE 2
96
97 extern int extra_time_offset;
98
99 static bool defaults_saved = False;
100
101 typedef struct _param_opt_struct param_opt_struct;
102 struct _param_opt_struct {
103         param_opt_struct *prev, *next;
104         char *key;
105         char *value;
106         char **list;
107 };
108
109 /*
110  * This structure describes global (ie., server-wide) parameters.
111  */
112 struct global {
113         int ConfigBackend;
114         char *smb_ports;
115         char *dos_charset;
116         char *unix_charset;
117         char *display_charset;
118         char *szPrintcapname;
119         char *szAddPortCommand;
120         char *szEnumPortsCommand;
121         char *szAddPrinterCommand;
122         char *szDeletePrinterCommand;
123         char *szOs2DriverMap;
124         char *szLockDir;
125         char *szPidDir;
126         char *szRootdir;
127         char *szDefaultService;
128         char *szGetQuota;
129         char *szSetQuota;
130         char *szMsgCommand;
131         char *szServerString;
132         char *szAutoServices;
133         char *szPasswdProgram;
134         char *szPasswdChat;
135         char *szLogFile;
136         char *szConfigFile;
137         char *szSMBPasswdFile;
138         char *szPrivateDir;
139         char *szPassdbBackend;
140         char **szPreloadModules;
141         char *szPasswordServer;
142         char *szSocketOptions;
143         char *szRealm;
144         char *szAfsUsernameMap;
145         int iAfsTokenLifetime;
146         char *szLogNtTokenCommand;
147         char *szUsernameMap;
148         char *szLogonScript;
149         char *szLogonPath;
150         char *szLogonDrive;
151         char *szLogonHome;
152         char **szWINSservers;
153         char **szInterfaces;
154         char *szRemoteAnnounce;
155         char *szRemoteBrowseSync;
156         char *szSocketAddress;
157         char *szNISHomeMapName;
158         char *szAnnounceVersion;        /* This is initialised in init_globals */
159         char *szWorkgroup;
160         char *szNetbiosName;
161         char **szNetbiosAliases;
162         char *szNetbiosScope;
163         char *szNameResolveOrder;
164         char *szPanicAction;
165         char *szAddUserScript;
166         char *szRenameUserScript;
167         char *szDelUserScript;
168         char *szAddGroupScript;
169         char *szDelGroupScript;
170         char *szAddUserToGroupScript;
171         char *szDelUserFromGroupScript;
172         char *szSetPrimaryGroupScript;
173         char *szAddMachineScript;
174         char *szShutdownScript;
175         char *szAbortShutdownScript;
176         char *szUsernameMapScript;
177         char *szCheckPasswordScript;
178         char *szWINSHook;
179         char *szUtmpDir;
180         char *szWtmpDir;
181         bool bUtmp;
182         char *szIdmapUID;
183         char *szIdmapGID;
184         bool bPassdbExpandExplicit;
185         int AlgorithmicRidBase;
186         char *szTemplateHomedir;
187         char *szTemplateShell;
188         char *szWinbindSeparator;
189         bool bWinbindEnumUsers;
190         bool bWinbindEnumGroups;
191         bool bWinbindUseDefaultDomain;
192         bool bWinbindTrustedDomainsOnly;
193         bool bWinbindNestedGroups;
194         int  winbind_expand_groups;
195         bool bWinbindRefreshTickets;
196         bool bWinbindOfflineLogon;
197         bool bWinbindNormalizeNames;
198         bool bWinbindRpcOnly;
199         char **szIdmapDomains;
200         char **szIdmapBackend; /* deprecated */
201         char *szIdmapAllocBackend;
202         char *szAddShareCommand;
203         char *szChangeShareCommand;
204         char *szDeleteShareCommand;
205         char **szEventLogs;
206         char *szGuestaccount;
207         char *szManglingMethod;
208         char **szServicesList;
209         char *szUsersharePath;
210         char *szUsershareTemplateShare;
211         char **szUsersharePrefixAllowList;
212         char **szUsersharePrefixDenyList;
213         int mangle_prefix;
214         int max_log_size;
215         char *szLogLevel;
216         int max_xmit;
217         int max_mux;
218         int max_open_files;
219         int open_files_db_hash_size;
220         int pwordlevel;
221         int unamelevel;
222         int deadtime;
223         bool getwd_cache;
224         int maxprotocol;
225         int minprotocol;
226         int security;
227         char **AuthMethods;
228         bool paranoid_server_security;
229         int maxdisksize;
230         int lpqcachetime;
231         int iMaxSmbdProcesses;
232         bool bDisableSpoolss;
233         int syslog;
234         int os_level;
235         bool enhanced_browsing;
236         int max_ttl;
237         int max_wins_ttl;
238         int min_wins_ttl;
239         int lm_announce;
240         int lm_interval;
241         int announce_as;        /* This is initialised in init_globals */
242         int machine_password_timeout;
243         int map_to_guest;
244         int oplock_break_wait_time;
245         int winbind_cache_time;
246         int winbind_max_idle_children;
247         char **szWinbindNssInfo;
248         int iLockSpinTime;
249         char *szLdapMachineSuffix;
250         char *szLdapUserSuffix;
251         char *szLdapIdmapSuffix;
252         char *szLdapGroupSuffix;
253         int ldap_ssl;
254         char *szLdapSuffix;
255         char *szLdapAdminDn;
256         int ldap_debug_level;
257         int ldap_debug_threshold;
258         int iAclCompat;
259         char *szCupsServer;
260         char *szIPrintServer;
261         char *ctdbdSocket;
262         char **szClusterAddresses;
263         bool clustering;
264         int ldap_passwd_sync;
265         int ldap_replication_sleep;
266         int ldap_timeout; /* This is initialised in init_globals */
267         int ldap_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 page size",
3567                 .type           = P_INTEGER,
3568                 .p_class        = P_GLOBAL,
3569                 .ptr            = &Globals.ldap_page_size,
3570                 .special        = NULL,
3571                 .enum_list      = NULL,
3572                 .flags          = FLAG_ADVANCED,
3573         },
3574         {
3575                 .label          = "ldap user suffix",
3576                 .type           = P_STRING,
3577                 .p_class        = P_GLOBAL,
3578                 .ptr            = &Globals.szLdapUserSuffix,
3579                 .special        = NULL,
3580                 .enum_list      = NULL,
3581                 .flags          = FLAG_ADVANCED,
3582         },
3583         {
3584                 .label          = "ldap debug level",
3585                 .type           = P_INTEGER,
3586                 .p_class        = P_GLOBAL,
3587                 .ptr            = &Globals.ldap_debug_level,
3588                 .special        = handle_ldap_debug_level,
3589                 .enum_list      = NULL,
3590                 .flags          = FLAG_ADVANCED,
3591         },
3592         {
3593                 .label          = "ldap debug threshold",
3594                 .type           = P_INTEGER,
3595                 .p_class        = P_GLOBAL,
3596                 .ptr            = &Globals.ldap_debug_threshold,
3597                 .special        = NULL,
3598                 .enum_list      = NULL,
3599                 .flags          = FLAG_ADVANCED,
3600         },
3601
3602         {N_("EventLog Options"), P_SEP, P_SEPARATOR},
3603
3604         {
3605                 .label          = "eventlog list",
3606                 .type           = P_LIST,
3607                 .p_class        = P_GLOBAL,
3608                 .ptr            = &Globals.szEventLogs,
3609                 .special        = NULL,
3610                 .enum_list      = NULL,
3611                 .flags          = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
3612         },
3613
3614         {N_("Miscellaneous Options"), P_SEP, P_SEPARATOR},
3615
3616         {
3617                 .label          = "add share command",
3618                 .type           = P_STRING,
3619                 .p_class        = P_GLOBAL,
3620                 .ptr            = &Globals.szAddShareCommand,
3621                 .special        = NULL,
3622                 .enum_list      = NULL,
3623                 .flags          = FLAG_ADVANCED,
3624         },
3625         {
3626                 .label          = "change share command",
3627                 .type           = P_STRING,
3628                 .p_class        = P_GLOBAL,
3629                 .ptr            = &Globals.szChangeShareCommand,
3630                 .special        = NULL,
3631                 .enum_list      = NULL,
3632                 .flags          = FLAG_ADVANCED,
3633         },
3634         {
3635                 .label          = "delete share command",
3636                 .type           = P_STRING,
3637                 .p_class        = P_GLOBAL,
3638                 .ptr            = &Globals.szDeleteShareCommand,
3639                 .special        = NULL,
3640                 .enum_list      = NULL,
3641                 .flags          = FLAG_ADVANCED,
3642         },
3643         {
3644                 .label          = "config file",
3645                 .type           = P_STRING,
3646                 .p_class        = P_GLOBAL,
3647                 .ptr            = &Globals.szConfigFile,
3648                 .special        = NULL,
3649                 .enum_list      = NULL,
3650                 .flags          = FLAG_HIDE,
3651         },
3652         {
3653                 .label          = "preload",
3654                 .type           = P_STRING,
3655                 .p_class        = P_GLOBAL,
3656                 .ptr            = &Globals.szAutoServices,
3657                 .special        = NULL,
3658                 .enum_list      = NULL,
3659                 .flags          = FLAG_ADVANCED,
3660         },
3661         {
3662                 .label          = "auto services",
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          = "lock directory",
3672                 .type           = P_STRING,
3673                 .p_class        = P_GLOBAL,
3674                 .ptr            = &Globals.szLockDir,
3675                 .special        = NULL,
3676                 .enum_list      = NULL,
3677                 .flags          = FLAG_ADVANCED,
3678         },
3679         {
3680                 .label          = "lock dir",
3681                 .type           = P_STRING,
3682                 .p_class        = P_GLOBAL,
3683                 .ptr            = &Globals.szLockDir,
3684                 .special        = NULL,
3685                 .enum_list      = NULL,
3686                 .flags          = FLAG_HIDE,
3687         },
3688         {
3689                 .label          = "pid directory",
3690                 .type           = P_STRING,
3691                 .p_class        = P_GLOBAL,
3692                 .ptr            = &Globals.szPidDir,
3693                 .special        = NULL,
3694                 .enum_list      = NULL,
3695                 .flags          = FLAG_ADVANCED,
3696         },
3697 #ifdef WITH_UTMP
3698         {
3699                 .label          = "utmp directory",
3700                 .type           = P_STRING,
3701                 .p_class        = P_GLOBAL,
3702                 .ptr            = &Globals.szUtmpDir,
3703                 .special        = NULL,
3704                 .enum_list      = NULL,
3705                 .flags          = FLAG_ADVANCED,
3706         },
3707         {
3708                 .label          = "wtmp directory",
3709                 .type           = P_STRING,
3710                 .p_class        = P_GLOBAL,
3711                 .ptr            = &Globals.szWtmpDir,
3712                 .special        = NULL,
3713                 .enum_list      = NULL,
3714                 .flags          = FLAG_ADVANCED,
3715         },
3716         {
3717                 .label          = "utmp",
3718                 .type           = P_BOOL,
3719                 .p_class        = P_GLOBAL,
3720                 .ptr            = &Globals.bUtmp,
3721                 .special        = NULL,
3722                 .enum_list      = NULL,
3723                 .flags          = FLAG_ADVANCED,
3724         },
3725 #endif
3726         {
3727                 .label          = "default service",
3728                 .type           = P_STRING,
3729                 .p_class        = P_GLOBAL,
3730                 .ptr            = &Globals.szDefaultService,
3731                 .special        = NULL,
3732                 .enum_list      = NULL,
3733                 .flags          = FLAG_ADVANCED,
3734         },
3735         {
3736                 .label          = "default",
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          = "message command",
3746                 .type           = P_STRING,
3747                 .p_class        = P_GLOBAL,
3748                 .ptr            = &Globals.szMsgCommand,
3749                 .special        = NULL,
3750                 .enum_list      = NULL,
3751                 .flags          = FLAG_ADVANCED,
3752         },
3753         {
3754                 .label          = "dfree cache time",
3755                 .type           = P_INTEGER,
3756                 .p_class        = P_LOCAL,
3757                 .ptr            = &sDefault.iDfreeCacheTime,
3758                 .special        = NULL,
3759                 .enum_list      = NULL,
3760                 .flags          = FLAG_ADVANCED,
3761         },
3762         {
3763                 .label          = "dfree command",
3764                 .type           = P_STRING,
3765                 .p_class        = P_LOCAL,
3766                 .ptr            = &sDefault.szDfree,
3767                 .special        = NULL,
3768                 .enum_list      = NULL,
3769                 .flags          = FLAG_ADVANCED,
3770         },
3771         {
3772                 .label          = "get quota command",
3773                 .type           = P_STRING,
3774                 .p_class        = P_GLOBAL,
3775                 .ptr            = &Globals.szGetQuota,
3776                 .special        = NULL,
3777                 .enum_list      = NULL,
3778                 .flags          = FLAG_ADVANCED,
3779         },
3780         {
3781                 .label          = "set quota command",
3782                 .type           = P_STRING,
3783                 .p_class        = P_GLOBAL,
3784                 .ptr            = &Globals.szSetQuota,
3785                 .special        = NULL,
3786                 .enum_list      = NULL,
3787                 .flags          = FLAG_ADVANCED,
3788         },
3789         {
3790                 .label          = "remote announce",
3791                 .type           = P_STRING,
3792                 .p_class        = P_GLOBAL,
3793                 .ptr            = &Globals.szRemoteAnnounce,
3794                 .special        = NULL,
3795                 .enum_list      = NULL,
3796                 .flags          = FLAG_ADVANCED,
3797         },
3798         {
3799                 .label          = "remote browse sync",
3800                 .type           = P_STRING,
3801                 .p_class        = P_GLOBAL,
3802                 .ptr            = &Globals.szRemoteBrowseSync,
3803                 .special        = NULL,
3804                 .enum_list      = NULL,
3805                 .flags          = FLAG_ADVANCED,
3806         },
3807         {
3808                 .label          = "socket address",
3809                 .type           = P_STRING,
3810                 .p_class        = P_GLOBAL,
3811                 .ptr            = &Globals.szSocketAddress,
3812                 .special        = NULL,
3813                 .enum_list      = NULL,
3814                 .flags          = FLAG_ADVANCED,
3815         },
3816         {
3817                 .label          = "homedir map",
3818                 .type           = P_STRING,
3819                 .p_class        = P_GLOBAL,
3820                 .ptr            = &Globals.szNISHomeMapName,
3821                 .special        = NULL,
3822                 .enum_list      = NULL,
3823                 .flags          = FLAG_ADVANCED,
3824         },
3825         {
3826                 .label          = "afs username map",
3827                 .type           = P_STRING,
3828                 .p_class        = P_GLOBAL,
3829                 .ptr            = &Globals.szAfsUsernameMap,
3830                 .special        = NULL,
3831                 .enum_list      = NULL,
3832                 .flags          = FLAG_ADVANCED,
3833         },
3834         {
3835                 .label          = "afs token lifetime",
3836                 .type           = P_INTEGER,
3837                 .p_class        = P_GLOBAL,
3838                 .ptr            = &Globals.iAfsTokenLifetime,
3839                 .special        = NULL,
3840                 .enum_list      = NULL,
3841                 .flags          = FLAG_ADVANCED,
3842         },
3843         {
3844                 .label          = "log nt token command",
3845                 .type           = P_STRING,
3846                 .p_class        = P_GLOBAL,
3847                 .ptr            = &Globals.szLogNtTokenCommand,
3848                 .special        = NULL,
3849                 .enum_list      = NULL,
3850                 .flags          = FLAG_ADVANCED,
3851         },
3852         {
3853                 .label          = "time offset",
3854                 .type           = P_INTEGER,
3855                 .p_class        = P_GLOBAL,
3856                 .ptr            = &extra_time_offset,
3857                 .special        = NULL,
3858                 .enum_list      = NULL,
3859                 .flags          = FLAG_ADVANCED,
3860         },
3861         {
3862                 .label          = "NIS homedir",
3863                 .type           = P_BOOL,
3864                 .p_class        = P_GLOBAL,
3865                 .ptr            = &Globals.bNISHomeMap,
3866                 .special        = NULL,
3867                 .enum_list      = NULL,
3868                 .flags          = FLAG_ADVANCED,
3869         },
3870         {
3871                 .label          = "-valid",
3872                 .type           = P_BOOL,
3873                 .p_class        = P_LOCAL,
3874                 .ptr            = &sDefault.valid,
3875                 .special        = NULL,
3876                 .enum_list      = NULL,
3877                 .flags          = FLAG_HIDE,
3878         },
3879         {
3880                 .label          = "copy",
3881                 .type           = P_STRING,
3882                 .p_class        = P_LOCAL,
3883                 .ptr            = &sDefault.szCopy,
3884                 .special        = handle_copy,
3885                 .enum_list      = NULL,
3886                 .flags          = FLAG_HIDE,
3887         },
3888         {
3889                 .label          = "include",
3890                 .type           = P_STRING,
3891                 .p_class        = P_LOCAL,
3892                 .ptr            = &sDefault.szInclude,
3893                 .special        = handle_include,
3894                 .enum_list      = NULL,
3895                 .flags          = FLAG_HIDE,
3896         },
3897         {
3898                 .label          = "preexec",
3899                 .type           = P_STRING,
3900                 .p_class        = P_LOCAL,
3901                 .ptr            = &sDefault.szPreExec,
3902                 .special        = NULL,
3903                 .enum_list      = NULL,
3904                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3905         },
3906         {
3907                 .label          = "exec",
3908                 .type           = P_STRING,
3909                 .p_class        = P_LOCAL,
3910                 .ptr            = &sDefault.szPreExec,
3911                 .special        = NULL,
3912                 .enum_list      = NULL,
3913                 .flags          = FLAG_ADVANCED,
3914         },
3915         {
3916                 .label          = "preexec close",
3917                 .type           = P_BOOL,
3918                 .p_class        = P_LOCAL,
3919                 .ptr            = &sDefault.bPreexecClose,
3920                 .special        = NULL,
3921                 .enum_list      = NULL,
3922                 .flags          = FLAG_ADVANCED | FLAG_SHARE,
3923         },
3924         {
3925                 .label          = "postexec",
3926                 .type           = P_STRING,
3927                 .p_class        = P_LOCAL,
3928                 .ptr            = &sDefault.szPostExec,
3929                 .special        = NULL,
3930                 .enum_list      = NULL,
3931                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3932         },
3933         {
3934                 .label          = "root preexec",
3935                 .type           = P_STRING,
3936                 .p_class        = P_LOCAL,
3937                 .ptr            = &sDefault.szRootPreExec,
3938                 .special        = NULL,
3939                 .enum_list      = NULL,
3940                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3941         },
3942         {
3943                 .label          = "root preexec close",
3944                 .type           = P_BOOL,
3945                 .p_class        = P_LOCAL,
3946                 .ptr            = &sDefault.bRootpreexecClose,
3947                 .special        = NULL,
3948                 .enum_list      = NULL,
3949                 .flags          = FLAG_ADVANCED | FLAG_SHARE,
3950         },
3951         {
3952                 .label          = "root postexec",
3953                 .type           = P_STRING,
3954                 .p_class        = P_LOCAL,
3955                 .ptr            = &sDefault.szRootPostExec,
3956                 .special        = NULL,
3957                 .enum_list      = NULL,
3958                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3959         },
3960         {
3961                 .label          = "available",
3962                 .type           = P_BOOL,
3963                 .p_class        = P_LOCAL,
3964                 .ptr            = &sDefault.bAvailable,
3965                 .special        = NULL,
3966                 .enum_list      = NULL,
3967                 .flags          = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3968         },
3969         {
3970                 .label          = "registry shares",
3971                 .type           = P_BOOL,
3972                 .p_class        = P_GLOBAL,
3973                 .ptr            = &Globals.bRegistryShares,
3974                 .special        = NULL,
3975                 .enum_list      = NULL,
3976                 .flags          = FLAG_ADVANCED,
3977         },
3978         {
3979                 .label          = "usershare allow guests",
3980                 .type           = P_BOOL,
3981                 .p_class        = P_GLOBAL,
3982                 .ptr            = &Globals.bUsershareAllowGuests,
3983                 .special        = NULL,
3984                 .enum_list      = NULL,
3985                 .flags          = FLAG_ADVANCED,
3986         },
3987         {
3988                 .label          = "usershare max shares",
3989                 .type           = P_INTEGER,
3990                 .p_class        = P_GLOBAL,
3991                 .ptr            = &Globals.iUsershareMaxShares,
3992                 .special        = NULL,
3993                 .enum_list      = NULL,
3994                 .flags          = FLAG_ADVANCED,
3995         },
3996         {
3997                 .label          = "usershare owner only",
3998                 .type           = P_BOOL,
3999                 .p_class        = P_GLOBAL,
4000                 .ptr            = &Globals.bUsershareOwnerOnly,
4001                 .special        = NULL,
4002                 .enum_list      = NULL,
4003                 .flags          = FLAG_ADVANCED,
4004         },
4005         {
4006                 .label          = "usershare path",
4007                 .type           = P_STRING,
4008                 .p_class        = P_GLOBAL,
4009                 .ptr            = &Globals.szUsersharePath,
4010                 .special        = NULL,
4011                 .enum_list      = NULL,
4012                 .flags          = FLAG_ADVANCED,
4013         },
4014         {
4015                 .label          = "usershare prefix allow list",
4016                 .type           = P_LIST,
4017                 .p_class        = P_GLOBAL,
4018                 .ptr            = &Globals.szUsersharePrefixAllowList,
4019                 .special        = NULL,
4020                 .enum_list      = NULL,
4021                 .flags          = FLAG_ADVANCED,
4022         },
4023         {
4024                 .label          = "usershare prefix deny list",
4025                 .type           = P_LIST,
4026                 .p_class        = P_GLOBAL,
4027                 .ptr            = &Globals.szUsersharePrefixDenyList,
4028                 .special        = NULL,
4029                 .enum_list      = NULL,
4030                 .flags          = FLAG_ADVANCED,
4031         },
4032         {
4033                 .label          = "usershare template share",
4034                 .type           = P_STRING,
4035                 .p_class        = P_GLOBAL,
4036                 .ptr            = &Globals.szUsershareTemplateShare,
4037                 .special        = NULL,
4038                 .enum_list      = NULL,
4039                 .flags          = FLAG_ADVANCED,
4040         },
4041         {
4042                 .label          = "volume",
4043                 .type           = P_STRING,
4044                 .p_class        = P_LOCAL,
4045                 .ptr            = &sDefault.volume,
4046                 .special        = NULL,
4047                 .enum_list      = NULL,
4048                 .flags          = FLAG_ADVANCED | FLAG_SHARE,
4049         },
4050         {
4051                 .label          = "fstype",
4052                 .type           = P_STRING,
4053                 .p_class        = P_LOCAL,
4054                 .ptr            = &sDefault.fstype,
4055                 .special        = NULL,
4056                 .enum_list      = NULL,
4057                 .flags          = FLAG_ADVANCED | FLAG_SHARE,
4058         },
4059         {
4060                 .label          = "set directory",
4061                 .type           = P_BOOLREV,
4062                 .p_class        = P_LOCAL,
4063                 .ptr            = &sDefault.bNo_set_dir,
4064                 .special        = NULL,
4065                 .enum_list      = NULL,
4066                 .flags          = FLAG_ADVANCED | FLAG_SHARE,
4067         },
4068         {
4069                 .label          = "wide links",
4070                 .type           = P_BOOL,
4071                 .p_class        = P_LOCAL,
4072                 .ptr            = &sDefault.bWidelinks,
4073                 .special        = NULL,
4074                 .enum_list      = NULL,
4075                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4076         },
4077         {
4078                 .label          = "follow symlinks",
4079                 .type           = P_BOOL,
4080                 .p_class        = P_LOCAL,
4081                 .ptr            = &sDefault.bSymlinks,
4082                 .special        = NULL,
4083                 .enum_list      = NULL,
4084                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4085         },
4086         {
4087                 .label          = "dont descend",
4088                 .type           = P_STRING,
4089                 .p_class        = P_LOCAL,
4090                 .ptr            = &sDefault.szDontdescend,
4091                 .special        = NULL,
4092                 .enum_list      = NULL,
4093                 .flags          = FLAG_ADVANCED | FLAG_SHARE,
4094         },
4095         {
4096                 .label          = "magic script",
4097                 .type           = P_STRING,
4098                 .p_class        = P_LOCAL,
4099                 .ptr            = &sDefault.szMagicScript,
4100                 .special        = NULL,
4101                 .enum_list      = NULL,
4102                 .flags          = FLAG_ADVANCED | FLAG_SHARE,
4103         },
4104         {
4105                 .label          = "magic output",
4106                 .type           = P_STRING,
4107                 .p_class        = P_LOCAL,
4108                 .ptr            = &sDefault.szMagicOutput,
4109                 .special        = NULL,
4110                 .enum_list      = NULL,
4111                 .flags          = FLAG_ADVANCED | FLAG_SHARE,
4112         },
4113         {
4114                 .label          = "delete readonly",
4115                 .type           = P_BOOL,
4116                 .p_class        = P_LOCAL,
4117                 .ptr            = &sDefault.bDeleteReadonly,
4118                 .special        = NULL,
4119                 .enum_list      = NULL,
4120                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4121         },
4122         {
4123                 .label          = "dos filemode",
4124                 .type           = P_BOOL,
4125                 .p_class        = P_LOCAL,
4126                 .ptr            = &sDefault.bDosFilemode,
4127                 .special        = NULL,
4128                 .enum_list      = NULL,
4129                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4130         },
4131         {
4132                 .label          = "dos filetimes",
4133                 .type           = P_BOOL,
4134                 .p_class        = P_LOCAL,
4135                 .ptr            = &sDefault.bDosFiletimes,
4136                 .special        = NULL,
4137                 .enum_list      = NULL,
4138                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4139         },
4140         {
4141                 .label          = "dos filetime resolution",
4142                 .type           = P_BOOL,
4143                 .p_class        = P_LOCAL,
4144                 .ptr            = &sDefault.bDosFiletimeResolution,
4145                 .special        = NULL,
4146                 .enum_list      = NULL,
4147                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4148         },
4149         {
4150                 .label          = "fake directory create times",
4151                 .type           = P_BOOL,
4152                 .p_class        = P_LOCAL,
4153                 .ptr            = &sDefault.bFakeDirCreateTimes,
4154                 .special        = NULL,
4155                 .enum_list      = NULL,
4156                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4157         },
4158         {
4159                 .label          = "panic action",
4160                 .type           = P_STRING,
4161                 .p_class        = P_GLOBAL,
4162                 .ptr            = &Globals.szPanicAction,
4163                 .special        = NULL,
4164                 .enum_list      = NULL,
4165                 .flags          = FLAG_ADVANCED,
4166         },
4167
4168         {N_("VFS module options"), P_SEP, P_SEPARATOR},
4169
4170         {
4171                 .label          = "vfs objects",
4172                 .type           = P_LIST,
4173                 .p_class        = P_LOCAL,
4174                 .ptr            = &sDefault.szVfsObjects,
4175                 .special        = NULL,
4176                 .enum_list      = NULL,
4177                 .flags          = FLAG_ADVANCED | FLAG_SHARE,
4178         },
4179         {
4180                 .label          = "vfs object",
4181                 .type           = P_LIST,
4182                 .p_class        = P_LOCAL,
4183                 .ptr            = &sDefault.szVfsObjects,
4184                 .special        = NULL,
4185                 .enum_list      = NULL,
4186                 .flags          = FLAG_HIDE,
4187         },
4188
4189
4190         {N_("MSDFS options"), P_SEP, P_SEPARATOR},
4191
4192         {
4193                 .label          = "msdfs root",
4194                 .type           = P_BOOL,
4195                 .p_class        = P_LOCAL,
4196                 .ptr            = &sDefault.bMSDfsRoot,
4197                 .special        = NULL,
4198                 .enum_list      = NULL,
4199                 .flags          = FLAG_ADVANCED | FLAG_SHARE,
4200         },
4201         {
4202                 .label          = "msdfs proxy",
4203                 .type           = P_STRING,
4204                 .p_class        = P_LOCAL,
4205                 .ptr            = &sDefault.szMSDfsProxy,
4206                 .special        = NULL,
4207                 .enum_list      = NULL,
4208                 .flags          = FLAG_ADVANCED | FLAG_SHARE,
4209         },
4210         {
4211                 .label          = "host msdfs",
4212                 .type           = P_BOOL,
4213                 .p_class        = P_GLOBAL,
4214                 .ptr            = &Globals.bHostMSDfs,
4215                 .special        = NULL,
4216                 .enum_list      = NULL,
4217                 .flags          = FLAG_ADVANCED,
4218         },
4219
4220         {N_("Winbind options"), P_SEP, P_SEPARATOR},
4221
4222         {
4223                 .label          = "passdb expand explicit",
4224                 .type           = P_BOOL,
4225                 .p_class        = P_GLOBAL,
4226                 .ptr            = &Globals.bPassdbExpandExplicit,
4227                 .special        = NULL,
4228                 .enum_list      = NULL,
4229                 .flags          = FLAG_ADVANCED,
4230         },
4231         {
4232                 .label          = "idmap domains",
4233                 .type           = P_LIST,
4234                 .p_class        = P_GLOBAL,
4235                 .ptr            = &Globals.szIdmapDomains,
4236                 .special        = NULL,
4237                 .enum_list      = NULL,
4238                 .flags          = FLAG_ADVANCED,
4239         },
4240         {
4241                 .label          = "idmap backend",
4242                 .type           = P_LIST,
4243                 .p_class        = P_GLOBAL,
4244                 .ptr            = &Globals.szIdmapBackend,
4245                 .special        = NULL,
4246                 .enum_list      = NULL,
4247                 .flags          = FLAG_ADVANCED,
4248         },
4249         {
4250                 .label          = "idmap alloc backend",
4251                 .type           = P_STRING,
4252                 .p_class        = P_GLOBAL,
4253                 .ptr            = &Globals.szIdmapAllocBackend,
4254                 .special        = NULL,
4255                 .enum_list      = NULL,
4256                 .flags          = FLAG_ADVANCED,
4257         },
4258         {
4259                 .label          = "idmap cache time",
4260                 .type           = P_INTEGER,
4261                 .p_class        = P_GLOBAL,
4262                 .ptr            = &Globals.iIdmapCacheTime,
4263                 .special        = NULL,
4264                 .enum_list      = NULL,
4265                 .flags          = FLAG_ADVANCED,
4266         },
4267         {
4268                 .label          = "idmap negative cache time",
4269                 .type           = P_INTEGER,
4270                 .p_class        = P_GLOBAL,
4271                 .ptr            = &Globals.iIdmapNegativeCacheTime,
4272                 .special        = NULL,
4273                 .enum_list      = NULL,
4274                 .flags          = FLAG_ADVANCED,
4275         },
4276         {
4277                 .label          = "idmap uid",
4278                 .type           = P_STRING,
4279                 .p_class        = P_GLOBAL,
4280                 .ptr            = &Globals.szIdmapUID,
4281                 .special        = handle_idmap_uid,
4282                 .enum_list      = NULL,
4283                 .flags          = FLAG_ADVANCED,
4284         },
4285         {
4286                 .label          = "winbind 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_HIDE,
4293         },
4294         {
4295                 .label          = "idmap gid",
4296                 .type           = P_STRING,
4297                 .p_class        = P_GLOBAL,
4298                 .ptr            = &Globals.szIdmapGID,
4299                 .special        = handle_idmap_gid,
4300                 .enum_list      = NULL,
4301                 .flags          = FLAG_ADVANCED,
4302         },
4303         {
4304                 .label          = "winbind 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_HIDE,
4311         },
4312         {
4313                 .label          = "template homedir",
4314                 .type           = P_STRING,
4315                 .p_class        = P_GLOBAL,
4316                 .ptr            = &Globals.szTemplateHomedir,
4317                 .special        = NULL,
4318                 .enum_list      = NULL,
4319                 .flags          = FLAG_ADVANCED,
4320         },
4321         {
4322                 .label          = "template shell",
4323                 .type           = P_STRING,
4324                 .p_class        = P_GLOBAL,
4325                 .ptr            = &Globals.szTemplateShell,
4326                 .special        = NULL,
4327                 .enum_list      = NULL,
4328                 .flags          = FLAG_ADVANCED,
4329         },
4330         {
4331                 .label          = "winbind separator",
4332                 .type           = P_STRING,
4333                 .p_class        = P_GLOBAL,
4334                 .ptr            = &Globals.szWinbindSeparator,
4335                 .special        = NULL,
4336                 .enum_list      = NULL,
4337                 .flags          = FLAG_ADVANCED,
4338         },
4339         {
4340                 .label          = "winbind cache time",
4341                 .type           = P_INTEGER,
4342                 .p_class        = P_GLOBAL,
4343                 .ptr            = &Globals.winbind_cache_time,
4344                 .special        = NULL,
4345                 .enum_list      = NULL,
4346                 .flags          = FLAG_ADVANCED,
4347         },
4348         {
4349                 .label          = "winbind enum users",
4350                 .type           = P_BOOL,
4351                 .p_class        = P_GLOBAL,
4352                 .ptr            = &Globals.bWinbindEnumUsers,
4353                 .special        = NULL,
4354                 .enum_list      = NULL,
4355                 .flags          = FLAG_ADVANCED,
4356         },
4357         {
4358                 .label          = "winbind enum groups",
4359                 .type           = P_BOOL,
4360                 .p_class        = P_GLOBAL,
4361                 .ptr            = &Globals.bWinbindEnumGroups,
4362                 .special        = NULL,
4363                 .enum_list      = NULL,
4364                 .flags          = FLAG_ADVANCED,
4365         },
4366         {
4367                 .label          = "winbind use default domain",
4368                 .type           = P_BOOL,
4369                 .p_class        = P_GLOBAL,
4370                 .ptr            = &Globals.bWinbindUseDefaultDomain,
4371                 .special        = NULL,
4372                 .enum_list      = NULL,
4373                 .flags          = FLAG_ADVANCED,
4374         },
4375         {
4376                 .label          = "winbind trusted domains only",
4377                 .type           = P_BOOL,
4378                 .p_class        = P_GLOBAL,
4379                 .ptr            = &Globals.bWinbindTrustedDomainsOnly,
4380                 .special        = NULL,
4381                 .enum_list      = NULL,
4382                 .flags          = FLAG_ADVANCED,
4383         },
4384         {
4385                 .label          = "winbind nested groups",
4386                 .type           = P_BOOL,
4387                 .p_class        = P_GLOBAL,
4388                 .ptr            = &Globals.bWinbindNestedGroups,
4389                 .special        = NULL,
4390                 .enum_list      = NULL,
4391                 .flags          = FLAG_ADVANCED,
4392         },
4393         {
4394                 .label          = "winbind expand groups",
4395                 .type           = P_INTEGER,
4396                 .p_class        = P_GLOBAL,
4397                 .ptr            = &Globals.winbind_expand_groups,
4398                 .special        = NULL,
4399                 .enum_list      = NULL,
4400                 .flags          = FLAG_ADVANCED,
4401         },
4402         {
4403                 .label          = "winbind nss info",
4404                 .type           = P_LIST,
4405                 .p_class        = P_GLOBAL,
4406                 .ptr            = &Globals.szWinbindNssInfo,
4407                 .special        = NULL,
4408                 .enum_list      = NULL,
4409                 .flags          = FLAG_ADVANCED,
4410         },
4411         {
4412                 .label          = "winbind refresh tickets",
4413                 .type           = P_BOOL,
4414                 .p_class        = P_GLOBAL,
4415                 .ptr            = &Globals.bWinbindRefreshTickets,
4416                 .special        = NULL,
4417                 .enum_list      = NULL,
4418                 .flags          = FLAG_ADVANCED,
4419         },
4420         {
4421                 .label          = "winbind offline logon",
4422                 .type           = P_BOOL,
4423                 .p_class        = P_GLOBAL,
4424                 .ptr            = &Globals.bWinbindOfflineLogon,
4425                 .special        = NULL,
4426                 .enum_list      = NULL,
4427                 .flags          = FLAG_ADVANCED,
4428         },
4429         {
4430                 .label          = "winbind normalize names",
4431                 .type           = P_BOOL,
4432                 .p_class        = P_GLOBAL,
4433                 .ptr            = &Globals.bWinbindNormalizeNames,
4434                 .special        = NULL,
4435                 .enum_list      = NULL,
4436                 .flags          = FLAG_ADVANCED,
4437         },
4438         {
4439                 .label          = "winbind rpc only",
4440                 .type           = P_BOOL,
4441                 .p_class        = P_GLOBAL,
4442                 .ptr            = &Globals.bWinbindRpcOnly,
4443                 .special        = NULL,
4444                 .enum_list      = NULL,
4445                 .flags          = FLAG_ADVANCED,
4446         },
4447
4448         {NULL,  P_BOOL,  P_NONE,  NULL,  NULL,  NULL,  0}
4449 };
4450
4451 /***************************************************************************
4452  Initialise the sDefault parameter structure for the printer values.
4453 ***************************************************************************/
4454
4455 static void init_printer_values(struct service *pService)
4456 {
4457         /* choose defaults depending on the type of printing */
4458         switch (pService->iPrinting) {
4459                 case PRINT_BSD:
4460                 case PRINT_AIX:
4461                 case PRINT_LPRNT:
4462                 case PRINT_LPROS2:
4463                         string_set(&pService->szLpqcommand, "lpq -P'%p'");
4464                         string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4465                         string_set(&pService->szPrintcommand, "lpr -r -P'%p' %s");
4466                         break;
4467
4468                 case PRINT_LPRNG:
4469                 case PRINT_PLP:
4470                         string_set(&pService->szLpqcommand, "lpq -P'%p'");
4471                         string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4472                         string_set(&pService->szPrintcommand, "lpr -r -P'%p' %s");
4473                         string_set(&pService->szQueuepausecommand, "lpc stop '%p'");
4474                         string_set(&pService->szQueueresumecommand, "lpc start '%p'");
4475                         string_set(&pService->szLppausecommand, "lpc hold '%p' %j");
4476                         string_set(&pService->szLpresumecommand, "lpc release '%p' %j");
4477                         break;
4478
4479                 case PRINT_CUPS:
4480                 case PRINT_IPRINT:
4481 #ifdef HAVE_CUPS
4482                         /* set the lpq command to contain the destination printer
4483                            name only.  This is used by cups_queue_get() */
4484                         string_set(&pService->szLpqcommand, "%p");
4485                         string_set(&pService->szLprmcommand, "");
4486                         string_set(&pService->szPrintcommand, "");
4487                         string_set(&pService->szLppausecommand, "");
4488                         string_set(&pService->szLpresumecommand, "");
4489                         string_set(&pService->szQueuepausecommand, "");
4490                         string_set(&pService->szQueueresumecommand, "");
4491 #else
4492                         string_set(&pService->szLpqcommand, "lpq -P'%p'");
4493                         string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4494                         string_set(&pService->szPrintcommand, "lpr -P'%p' %s; rm %s");
4495                         string_set(&pService->szLppausecommand, "lp -i '%p-%j' -H hold");
4496                         string_set(&pService->szLpresumecommand, "lp -i '%p-%j' -H resume");
4497                         string_set(&pService->szQueuepausecommand, "disable '%p'");
4498                         string_set(&pService->szQueueresumecommand, "enable '%p'");
4499 #endif /* HAVE_CUPS */
4500                         break;
4501
4502                 case PRINT_SYSV:
4503                 case PRINT_HPUX:
4504                         string_set(&pService->szLpqcommand, "lpstat -o%p");
4505                         string_set(&pService->szLprmcommand, "cancel %p-%j");
4506                         string_set(&pService->szPrintcommand, "lp -c -d%p %s; rm %s");
4507                         string_set(&pService->szQueuepausecommand, "disable %p");
4508                         string_set(&pService->szQueueresumecommand, "enable %p");
4509 #ifndef HPUX
4510                         string_set(&pService->szLppausecommand, "lp -i %p-%j -H hold");
4511                         string_set(&pService->szLpresumecommand, "lp -i %p-%j -H resume");
4512 #endif /* HPUX */
4513                         break;
4514
4515                 case PRINT_QNX:
4516                         string_set(&pService->szLpqcommand, "lpq -P%p");
4517                         string_set(&pService->szLprmcommand, "lprm -P%p %j");
4518                         string_set(&pService->szPrintcommand, "lp -r -P%p %s");
4519                         break;
4520
4521 #ifdef DEVELOPER
4522         case PRINT_TEST:
4523         case PRINT_VLP:
4524                 string_set(&pService->szPrintcommand, "vlp print %p %s");
4525                 string_set(&pService->szLpqcommand, "vlp lpq %p");
4526                 string_set(&pService->szLprmcommand, "vlp lprm %p %j");
4527                 string_set(&pService->szLppausecommand, "vlp lppause %p %j");
4528                 string_set(&pService->szLpresumecommand, "vlp lpresum %p %j");
4529                 string_set(&pService->szQueuepausecommand, "vlp queuepause %p");
4530                 string_set(&pService->szQueueresumecommand, "vlp queueresume %p");
4531                 break;
4532 #endif /* DEVELOPER */
4533
4534         }
4535 }
4536
4537 /***************************************************************************
4538  Initialise the global parameter structure.
4539 ***************************************************************************/
4540
4541 static void init_globals(bool first_time_only)
4542 {
4543         static bool done_init = False;
4544         char *s = NULL;
4545         int i;
4546
4547         /* If requested to initialize only once and we've already done it... */
4548         if (first_time_only && done_init) {
4549                 /* ... then we have nothing more to do */
4550                 return;
4551         }
4552
4553         if (!done_init) {
4554                 /* The logfile can be set before this is invoked. Free it if so. */
4555                 if (Globals.szLogFile != NULL) {
4556                         string_free(&Globals.szLogFile);
4557                         Globals.szLogFile = NULL;
4558                 }
4559                 done_init = True;
4560         } else {
4561                 for (i = 0; parm_table[i].label; i++) {
4562                         if ((parm_table[i].type == P_STRING ||
4563                              parm_table[i].type == P_USTRING) &&
4564                             parm_table[i].ptr)
4565                         {
4566                                 string_free((char **)parm_table[i].ptr);
4567                         }
4568                 }
4569         }
4570
4571         memset((void *)&Globals, '\0', sizeof(Globals));
4572
4573         for (i = 0; parm_table[i].label; i++) {
4574                 if ((parm_table[i].type == P_STRING ||
4575                      parm_table[i].type == P_USTRING) &&
4576                     parm_table[i].ptr)
4577                 {
4578                         string_set((char **)parm_table[i].ptr, "");
4579                 }
4580         }
4581
4582         string_set(&sDefault.fstype, FSTYPE_STRING);
4583         string_set(&sDefault.szPrintjobUsername, "%U");
4584
4585         init_printer_values(&sDefault);
4586
4587
4588         DEBUG(3, ("Initialising global parameters\n"));
4589
4590         string_set(&Globals.szSMBPasswdFile, get_dyn_SMB_PASSWD_FILE());
4591         string_set(&Globals.szPrivateDir, get_dyn_PRIVATE_DIR());
4592
4593         /* use the new 'hash2' method by default, with a prefix of 1 */
4594         string_set(&Globals.szManglingMethod, "hash2");
4595         Globals.mangle_prefix = 1;
4596
4597         string_set(&Globals.szGuestaccount, GUEST_ACCOUNT);
4598
4599         /* using UTF8 by default allows us to support all chars */
4600         string_set(&Globals.unix_charset, DEFAULT_UNIX_CHARSET);
4601
4602 #if defined(HAVE_NL_LANGINFO) && defined(CODESET)
4603         /* If the system supports nl_langinfo(), try to grab the value
4604            from the user's locale */
4605         string_set(&Globals.display_charset, "LOCALE");
4606 #else
4607         string_set(&Globals.display_charset, DEFAULT_DISPLAY_CHARSET);
4608 #endif
4609
4610         /* Use codepage 850 as a default for the dos character set */
4611         string_set(&Globals.dos_charset, DEFAULT_DOS_CHARSET);
4612
4613         /*
4614          * Allow the default PASSWD_CHAT to be overridden in local.h.
4615          */
4616         string_set(&Globals.szPasswdChat, DEFAULT_PASSWD_CHAT);
4617
4618         set_global_myname(myhostname());
4619         string_set(&Globals.szNetbiosName,global_myname());
4620
4621         set_global_myworkgroup(WORKGROUP);
4622         string_set(&Globals.szWorkgroup, lp_workgroup());
4623
4624         string_set(&Globals.szPasswdProgram, "");
4625         string_set(&Globals.szPidDir, get_dyn_PIDDIR());
4626         string_set(&Globals.szLockDir, get_dyn_LOCKDIR());
4627         string_set(&Globals.szSocketAddress, "0.0.0.0");
4628
4629         if (asprintf(&s, "Samba %s", SAMBA_VERSION_STRING) < 0) {
4630                 smb_panic("init_globals: ENOMEM");
4631         }
4632         string_set(&Globals.szServerString, s);
4633         SAFE_FREE(s);
4634         if (asprintf(&s, "%d.%d", DEFAULT_MAJOR_VERSION,
4635                         DEFAULT_MINOR_VERSION) < 0) {
4636                 smb_panic("init_globals: ENOMEM");
4637         }
4638         string_set(&Globals.szAnnounceVersion, s);
4639         SAFE_FREE(s);
4640 #ifdef DEVELOPER
4641         string_set(&Globals.szPanicAction, "/bin/sleep 999999999");
4642 #endif
4643
4644         string_set(&Globals.szSocketOptions, DEFAULT_SOCKET_OPTIONS);
4645
4646         string_set(&Globals.szLogonDrive, "");
4647         /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
4648         string_set(&Globals.szLogonHome, "\\\\%N\\%U");
4649         string_set(&Globals.szLogonPath, "\\\\%N\\%U\\profile");
4650
4651         string_set(&Globals.szNameResolveOrder, "lmhosts wins host bcast");
4652         string_set(&Globals.szPasswordServer, "*");
4653
4654         Globals.AlgorithmicRidBase = BASE_RID;
4655
4656         Globals.bLoadPrinters = True;
4657         Globals.PrintcapCacheTime = 750;        /* 12.5 minutes */
4658
4659         Globals.ConfigBackend = config_backend;
4660
4661         /* Was 65535 (0xFFFF). 0x4101 matches W2K and causes major speed improvements... */
4662         /* Discovered by 2 days of pain by Don McCall @ HP :-). */
4663         Globals.max_xmit = 0x4104;
4664         Globals.max_mux = 50;   /* This is *needed* for profile support. */
4665         Globals.lpqcachetime = 30;      /* changed to handle large print servers better -- jerry */
4666         Globals.bDisableSpoolss = False;
4667         Globals.iMaxSmbdProcesses = 0;/* no limit specified */
4668         Globals.pwordlevel = 0;
4669         Globals.unamelevel = 0;
4670         Globals.deadtime = 0;
4671         Globals.getwd_cache = true;
4672         Globals.bLargeReadwrite = True;
4673         Globals.max_log_size = 5000;
4674         Globals.max_open_files = MAX_OPEN_FILES;
4675         Globals.open_files_db_hash_size = SMB_OPEN_DATABASE_TDB_HASH_SIZE;
4676         Globals.maxprotocol = PROTOCOL_NT1;
4677         Globals.minprotocol = PROTOCOL_CORE;
4678         Globals.security = SEC_USER;
4679         Globals.paranoid_server_security = True;
4680         Globals.bEncryptPasswords = True;
4681         Globals.bUpdateEncrypt = False;
4682         Globals.clientSchannel = Auto;
4683         Globals.serverSchannel = Auto;
4684         Globals.bReadRaw = True;
4685         Globals.bWriteRaw = True;
4686         Globals.bNullPasswords = False;
4687         Globals.bObeyPamRestrictions = False;
4688         Globals.syslog = 1;
4689         Globals.bSyslogOnly = False;
4690         Globals.bTimestampLogs = True;
4691         string_set(&Globals.szLogLevel, "0");
4692         Globals.bDebugPrefixTimestamp = False;
4693         Globals.bDebugHiresTimestamp = False;
4694         Globals.bDebugPid = False;
4695         Globals.bDebugUid = False;
4696         Globals.bDebugClass = False;
4697         Globals.bEnableCoreFiles = True;
4698         Globals.max_ttl = 60 * 60 * 24 * 3;     /* 3 days default. */
4699         Globals.max_wins_ttl = 60 * 60 * 24 * 6;        /* 6 days default. */
4700         Globals.min_wins_ttl = 60 * 60 * 6;     /* 6 hours default. */
4701         Globals.machine_password_timeout = 60 * 60 * 24 * 7;    /* 7 days default. */
4702         Globals.lm_announce = 2;        /* = Auto: send only if LM clients found */
4703         Globals.lm_interval = 60;
4704         Globals.announce_as = ANNOUNCE_AS_NT_SERVER;
4705 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
4706         Globals.bNISHomeMap = False;
4707 #ifdef WITH_NISPLUS_HOME
4708         string_set(&Globals.szNISHomeMapName, "auto_home.org_dir");
4709 #else
4710         string_set(&Globals.szNISHomeMapName, "auto.home");
4711 #endif
4712 #endif
4713         Globals.bTimeServer = False;
4714         Globals.bBindInterfacesOnly = False;
4715         Globals.bUnixPasswdSync = False;
4716         Globals.bPamPasswordChange = False;
4717         Globals.bPasswdChatDebug = False;
4718         Globals.iPasswdChatTimeout = 2; /* 2 second default. */
4719         Globals.bNTPipeSupport = True;  /* Do NT pipes by default. */
4720         Globals.bNTStatusSupport = True; /* Use NT status by default. */
4721         Globals.bStatCache = True;      /* use stat cache by default */
4722         Globals.iMaxStatCacheSize = 256; /* 256k by default */
4723         Globals.restrict_anonymous = 0;
4724         Globals.bClientLanManAuth = False;      /* Do NOT use the LanMan hash if it is available */
4725         Globals.bClientPlaintextAuth = False;   /* Do NOT use a plaintext password even if is requested by the server */
4726         Globals.bLanmanAuth = False;    /* Do NOT use the LanMan hash, even if it is supplied */
4727         Globals.bNTLMAuth = True;       /* Do use NTLMv1 if it is supplied by the client (otherwise NTLMv2) */
4728         Globals.bClientNTLMv2Auth = False; /* Client should not use NTLMv2, as we can't tell that the server supports it. */
4729         /* Note, that we will use NTLM2 session security (which is different), if it is available */
4730
4731         Globals.map_to_guest = 0;       /* By Default, "Never" */
4732         Globals.oplock_break_wait_time = 0;     /* By Default, 0 msecs. */
4733         Globals.enhanced_browsing = true;
4734         Globals.iLockSpinTime = WINDOWS_MINIMUM_LOCK_TIMEOUT_MS; /* msec. */
4735 #ifdef MMAP_BLACKLIST
4736         Globals.bUseMmap = False;
4737 #else
4738         Globals.bUseMmap = True;
4739 #endif
4740         Globals.bUnixExtensions = True;
4741         Globals.bResetOnZeroVC = False;
4742
4743         /* hostname lookups can be very expensive and are broken on
4744            a large number of sites (tridge) */
4745         Globals.bHostnameLookups = False;
4746
4747         string_set(&Globals.szPassdbBackend, "smbpasswd");
4748         string_set(&Globals.szLdapSuffix, "");
4749         string_set(&Globals.szLdapMachineSuffix, "");
4750         string_set(&Globals.szLdapUserSuffix, "");
4751         string_set(&Globals.szLdapGroupSuffix, "");
4752         string_set(&Globals.szLdapIdmapSuffix, "");
4753
4754         string_set(&Globals.szLdapAdminDn, "");
4755         Globals.ldap_ssl = LDAP_SSL_ON;
4756         Globals.ldap_passwd_sync = LDAP_PASSWD_SYNC_OFF;
4757         Globals.ldap_delete_dn = False;
4758         Globals.ldap_replication_sleep = 1000; /* wait 1 sec for replication */
4759         Globals.ldap_timeout = LDAP_CONNECT_DEFAULT_TIMEOUT;
4760         Globals.ldap_page_size = LDAP_PAGE_SIZE;
4761
4762         Globals.ldap_debug_level = 0;
4763         Globals.ldap_debug_threshold = 10;
4764
4765         /* This is what we tell the afs client. in reality we set the token 
4766          * to never expire, though, when this runs out the afs client will 
4767          * forget the token. Set to 0 to get NEVERDATE.*/
4768         Globals.iAfsTokenLifetime = 604800;
4769
4770 /* these parameters are set to defaults that are more appropriate
4771    for the increasing samba install base:
4772
4773    as a member of the workgroup, that will possibly become a
4774    _local_ master browser (lm = True).  this is opposed to a forced
4775    local master browser startup (pm = True).
4776
4777    doesn't provide WINS server service by default (wsupp = False),
4778    and doesn't provide domain master browser services by default, either.
4779
4780 */
4781
4782         Globals.bMsAddPrinterWizard = True;
4783         Globals.os_level = 20;
4784         Globals.bLocalMaster = True;
4785         Globals.iDomainMaster = Auto;   /* depending on bDomainLogons */
4786         Globals.bDomainLogons = False;
4787         Globals.bBrowseList = True;
4788         Globals.bWINSsupport = False;
4789         Globals.bWINSproxy = False;
4790
4791         Globals.bDNSproxy = True;
4792
4793         /* this just means to use them if they exist */
4794         Globals.bKernelOplocks = True;
4795
4796         Globals.bAllowTrustedDomains = True;
4797
4798         string_set(&Globals.szTemplateShell, "/bin/false");
4799         string_set(&Globals.szTemplateHomedir, "/home/%D/%U");
4800         string_set(&Globals.szWinbindSeparator, "\\");
4801
4802         string_set(&Globals.szCupsServer, "");
4803         string_set(&Globals.szIPrintServer, "");
4804
4805         string_set(&Globals.ctdbdSocket, "");
4806         Globals.szClusterAddresses = NULL;
4807         Globals.clustering = False;
4808
4809         Globals.winbind_cache_time = 300;       /* 5 minutes */
4810         Globals.bWinbindEnumUsers = False;
4811         Globals.bWinbindEnumGroups = False;
4812         Globals.bWinbindUseDefaultDomain = False;
4813         Globals.bWinbindTrustedDomainsOnly = False;
4814         Globals.bWinbindNestedGroups = True;
4815         Globals.winbind_expand_groups = 1;
4816         Globals.szWinbindNssInfo = str_list_make(NULL, "template", NULL);
4817         Globals.bWinbindRefreshTickets = False;
4818         Globals.bWinbindOfflineLogon = False;
4819
4820         Globals.iIdmapCacheTime = 900; /* 15 minutes by default */
4821         Globals.iIdmapNegativeCacheTime = 120; /* 2 minutes by default */
4822
4823         Globals.bPassdbExpandExplicit = False;
4824
4825         Globals.name_cache_timeout = 660; /* In seconds */
4826
4827         Globals.bUseSpnego = True;
4828         Globals.bClientUseSpnego = True;
4829
4830         Globals.client_signing = Auto;
4831         Globals.server_signing = False;
4832
4833         Globals.bDeferSharingViolations = True;
4834         string_set(&Globals.smb_ports, SMB_PORTS);
4835
4836         Globals.bEnablePrivileges = True;
4837         Globals.bHostMSDfs        = True;
4838         Globals.bASUSupport       = False;
4839
4840         /* User defined shares. */
4841         if (asprintf(&s, "%s/usershares", get_dyn_STATEDIR()) < 0) {
4842                 smb_panic("init_globals: ENOMEM");
4843         }
4844         string_set(&Globals.szUsersharePath, s);
4845         SAFE_FREE(s);
4846         string_set(&Globals.szUsershareTemplateShare, "");
4847         Globals.iUsershareMaxShares = 0;
4848         /* By default disallow sharing of directories not owned by the sharer. */
4849         Globals.bUsershareOwnerOnly = True;
4850         /* By default disallow guest access to usershares. */
4851         Globals.bUsershareAllowGuests = False;
4852
4853         Globals.iKeepalive = DEFAULT_KEEPALIVE;
4854
4855         /* By default no shares out of the registry */
4856         Globals.bRegistryShares = False;
4857
4858         Globals.iminreceivefile = 0;
4859 }
4860
4861 /*******************************************************************
4862  Convenience routine to grab string parameters into temporary memory
4863  and run standard_sub_basic on them. The buffers can be written to by
4864  callers without affecting the source string.
4865 ********************************************************************/
4866
4867 static char *lp_string(const char *s)
4868 {
4869         char *ret;
4870         TALLOC_CTX *ctx = talloc_tos();
4871
4872         /* The follow debug is useful for tracking down memory problems
4873            especially if you have an inner loop that is calling a lp_*()
4874            function that returns a string.  Perhaps this debug should be
4875            present all the time? */
4876
4877 #if 0
4878         DEBUG(10, ("lp_string(%s)\n", s));
4879 #endif
4880
4881         ret = talloc_sub_basic(ctx,
4882                         get_current_username(),
4883                         current_user_info.domain,
4884                         s);
4885         if (trim_char(ret, '\"', '\"')) {
4886                 if (strchr(ret,'\"') != NULL) {
4887                         TALLOC_FREE(ret);
4888                         ret = talloc_sub_basic(ctx,
4889                                         get_current_username(),
4890                                         current_user_info.domain,
4891                                         s);
4892                 }
4893         }
4894         return ret;
4895 }
4896
4897 /*
4898    In this section all the functions that are used to access the 
4899    parameters from the rest of the program are defined 
4900 */
4901
4902 #define FN_GLOBAL_STRING(fn_name,ptr) \
4903  char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
4904 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
4905  const char *fn_name(void) {return(*(const char **)(ptr) ? *(const char **)(ptr) : "");}
4906 #define FN_GLOBAL_LIST(fn_name,ptr) \
4907  const char **fn_name(void) {return(*(const char ***)(ptr));}
4908 #define FN_GLOBAL_BOOL(fn_name,ptr) \
4909  bool fn_name(void) {return(*(bool *)(ptr));}
4910 #define FN_GLOBAL_CHAR(fn_name,ptr) \
4911  char fn_name(void) {return(*(char *)(ptr));}
4912 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
4913  int fn_name(void) {return(*(int *)(ptr));}
4914
4915 #define FN_LOCAL_STRING(fn_name,val) \
4916  char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));}
4917 #define FN_LOCAL_CONST_STRING(fn_name,val) \
4918  const char *fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
4919 #define FN_LOCAL_LIST(fn_name,val) \
4920  const char **fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
4921 #define FN_LOCAL_BOOL(fn_name,val) \
4922  bool fn_name(int i) {return(bool)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
4923 #define FN_LOCAL_INTEGER(fn_name,val) \
4924  int fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
4925
4926 #define FN_LOCAL_PARM_BOOL(fn_name,val) \
4927  bool fn_name(const struct share_params *p) {return(bool)(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
4928 #define FN_LOCAL_PARM_INTEGER(fn_name,val) \
4929  int fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
4930 #define FN_LOCAL_PARM_STRING(fn_name,val) \
4931  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));}
4932 #define FN_LOCAL_CHAR(fn_name,val) \
4933  char fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
4934
4935 FN_GLOBAL_STRING(lp_smb_ports, &Globals.smb_ports)
4936 FN_GLOBAL_STRING(lp_dos_charset, &Globals.dos_charset)
4937 FN_GLOBAL_STRING(lp_unix_charset, &Globals.unix_charset)
4938 FN_GLOBAL_STRING(lp_display_charset, &Globals.display_charset)
4939 FN_GLOBAL_STRING(lp_logfile, &Globals.szLogFile)
4940 FN_GLOBAL_STRING(lp_configfile, &Globals.szConfigFile)
4941 FN_GLOBAL_STRING(lp_smb_passwd_file, &Globals.szSMBPasswdFile)
4942 FN_GLOBAL_STRING(lp_private_dir, &Globals.szPrivateDir)
4943 FN_GLOBAL_STRING(lp_serverstring, &Globals.szServerString)
4944 FN_GLOBAL_INTEGER(lp_printcap_cache_time, &Globals.PrintcapCacheTime)
4945 FN_GLOBAL_STRING(lp_addport_cmd, &Globals.szAddPortCommand)
4946 FN_GLOBAL_STRING(lp_enumports_cmd, &Globals.szEnumPortsCommand)
4947 FN_GLOBAL_STRING(lp_addprinter_cmd, &Globals.szAddPrinterCommand)
4948 FN_GLOBAL_STRING(lp_deleteprinter_cmd, &Globals.szDeletePrinterCommand)
4949 FN_GLOBAL_STRING(lp_os2_driver_map, &Globals.szOs2DriverMap)
4950 FN_GLOBAL_STRING(lp_lockdir, &Globals.szLockDir)
4951 FN_GLOBAL_STRING(lp_piddir, &Globals.szPidDir)
4952 FN_GLOBAL_STRING(lp_mangling_method, &Globals.szManglingMethod)
4953 FN_GLOBAL_INTEGER(lp_mangle_prefix, &Globals.mangle_prefix)
4954 FN_GLOBAL_STRING(lp_utmpdir, &Globals.szUtmpDir)
4955 FN_GLOBAL_STRING(lp_wtmpdir, &Globals.szWtmpDir)
4956 FN_GLOBAL_BOOL(lp_utmp, &Globals.bUtmp)
4957 FN_GLOBAL_STRING(lp_rootdir, &Globals.szRootdir)
4958 FN_GLOBAL_STRING(lp_defaultservice, &Globals.szDefaultService)
4959 FN_GLOBAL_STRING(lp_msg_command, &Globals.szMsgCommand)
4960 FN_GLOBAL_STRING(lp_get_quota_command, &Globals.szGetQuota)
4961 FN_GLOBAL_STRING(lp_set_quota_command, &Globals.szSetQuota)
4962 FN_GLOBAL_STRING(lp_auto_services, &Globals.szAutoServices)
4963 FN_GLOBAL_STRING(lp_passwd_program, &Globals.szPasswdProgram)
4964 FN_GLOBAL_STRING(lp_passwd_chat, &Globals.szPasswdChat)
4965 FN_GLOBAL_STRING(lp_passwordserver, &Globals.szPasswordServer)
4966 FN_GLOBAL_STRING(lp_name_resolve_order, &Globals.szNameResolveOrder)
4967 FN_GLOBAL_STRING(lp_realm, &Globals.szRealm)
4968 FN_GLOBAL_CONST_STRING(lp_afs_username_map, &Globals.szAfsUsernameMap)
4969 FN_GLOBAL_INTEGER(lp_afs_token_lifetime, &Globals.iAfsTokenLifetime)
4970 FN_GLOBAL_STRING(lp_log_nt_token_command, &Globals.szLogNtTokenCommand)
4971 FN_GLOBAL_STRING(lp_username_map, &Globals.szUsernameMap)
4972 FN_GLOBAL_CONST_STRING(lp_logon_script, &Globals.szLogonScript)
4973 FN_GLOBAL_CONST_STRING(lp_logon_path, &Globals.szLogonPath)
4974 FN_GLOBAL_CONST_STRING(lp_logon_drive, &Globals.szLogonDrive)
4975 FN_GLOBAL_CONST_STRING(lp_logon_home, &Globals.szLogonHome)
4976 FN_GLOBAL_STRING(lp_remote_announce, &Globals.szRemoteAnnounce)
4977 FN_GLOBAL_STRING(lp_remote_browse_sync, &Globals.szRemoteBrowseSync)
4978 FN_GLOBAL_LIST(lp_wins_server_list, &Globals.szWINSservers)
4979 FN_GLOBAL_LIST(lp_interfaces, &Globals.szInterfaces)
4980 FN_GLOBAL_STRING(lp_socket_address, &Globals.szSocketAddress)
4981 FN_GLOBAL_STRING(lp_nis_home_map_name, &Globals.szNISHomeMapName)
4982 static FN_GLOBAL_STRING(lp_announce_version, &Globals.szAnnounceVersion)
4983 FN_GLOBAL_LIST(lp_netbios_aliases, &Globals.szNetbiosAliases)
4984 /* FN_GLOBAL_STRING(lp_passdb_backend, &Globals.szPassdbBackend)
4985  * lp_passdb_backend() should be replace by the this macro again after
4986  * some releases.
4987  * */
4988 const char *lp_passdb_backend(void)
4989 {
4990         char *delim, *quote;
4991
4992         delim = strchr( Globals.szPassdbBackend, ' ');
4993         /* no space at all */
4994         if (delim == NULL) {
4995                 goto out;
4996         }
4997
4998         quote = strchr(Globals.szPassdbBackend, '"');
4999         /* no quote char or non in the first part */
5000         if (quote == NULL || quote > delim) {
5001                 *delim = '\0';
5002                 goto warn;
5003         }
5004
5005         quote = strchr(quote+1, '"');
5006         if (quote == NULL) {
5007                 DEBUG(0, ("WARNING: Your 'passdb backend' configuration is invalid due to a missing second \" char.\n"));
5008                 goto out;
5009         } else if (*(quote+1) == '\0') {
5010                 /* space, fitting quote char, and one backend only */
5011                 goto out;
5012         } else {
5013                 /* terminate string after the fitting quote char */
5014                 *(quote+1) = '\0';
5015         }
5016
5017 warn:
5018         DEBUG(0, ("WARNING: Your 'passdb backend' configuration includes multiple backends.  This\n"
5019                 "is deprecated since Samba 3.0.23.  Please check WHATSNEW.txt or the section 'Passdb\n"
5020                 "Changes' from the ChangeNotes as part of the Samba HOWTO collection.  Only the first\n"
5021                 "backend (%s) is used.  The rest is ignored.\n", Globals.szPassdbBackend));
5022
5023 out:
5024         return Globals.szPassdbBackend;
5025 }
5026 FN_GLOBAL_LIST(lp_preload_modules, &Globals.szPreloadModules)
5027 FN_GLOBAL_STRING(lp_panic_action, &Globals.szPanicAction)
5028 FN_GLOBAL_STRING(lp_adduser_script, &Globals.szAddUserScript)
5029 FN_GLOBAL_STRING(lp_renameuser_script, &Globals.szRenameUserScript)
5030 FN_GLOBAL_STRING(lp_deluser_script, &Globals.szDelUserScript)
5031
5032 FN_GLOBAL_CONST_STRING(lp_guestaccount, &Globals.szGuestaccount)
5033 FN_GLOBAL_STRING(lp_addgroup_script, &Globals.szAddGroupScript)
5034 FN_GLOBAL_STRING(lp_delgroup_script, &Globals.szDelGroupScript)
5035 FN_GLOBAL_STRING(lp_addusertogroup_script, &Globals.szAddUserToGroupScript)
5036 FN_GLOBAL_STRING(lp_deluserfromgroup_script, &Globals.szDelUserFromGroupScript)
5037 FN_GLOBAL_STRING(lp_setprimarygroup_script, &Globals.szSetPrimaryGroupScript)
5038
5039 FN_GLOBAL_STRING(lp_addmachine_script, &Globals.szAddMachineScript)
5040
5041 FN_GLOBAL_STRING(lp_shutdown_script, &Globals.szShutdownScript)
5042 FN_GLOBAL_STRING(lp_abort_shutdown_script, &Globals.szAbortShutdownScript)
5043 FN_GLOBAL_STRING(lp_username_map_script, &Globals.szUsernameMapScript)
5044
5045 FN_GLOBAL_STRING(lp_check_password_script, &Globals.szCheckPasswordScript)
5046
5047 FN_GLOBAL_STRING(lp_wins_hook, &Globals.szWINSHook)
5048 FN_GLOBAL_CONST_STRING(lp_template_homedir, &Globals.szTemplateHomedir)
5049 FN_GLOBAL_CONST_STRING(lp_template_shell, &Globals.szTemplateShell)
5050 FN_GLOBAL_CONST_STRING(lp_winbind_separator, &Globals.szWinbindSeparator)
5051 FN_GLOBAL_INTEGER(lp_acl_compatibility, &Globals.iAclCompat)
5052 FN_GLOBAL_BOOL(lp_winbind_enum_users, &Globals.bWinbindEnumUsers)
5053 FN_GLOBAL_BOOL(lp_winbind_enum_groups, &Globals.bWinbindEnumGroups)
5054 FN_GLOBAL_BOOL(lp_winbind_use_default_domain, &Globals.bWinbindUseDefaultDomain)
5055 FN_GLOBAL_BOOL(lp_winbind_trusted_domains_only, &Globals.bWinbindTrustedDomainsOnly)
5056 FN_GLOBAL_BOOL(lp_winbind_nested_groups, &Globals.bWinbindNestedGroups)
5057 FN_GLOBAL_INTEGER(lp_winbind_expand_groups, &Globals.winbind_expand_groups)
5058 FN_GLOBAL_BOOL(lp_winbind_refresh_tickets, &Globals.bWinbindRefreshTickets)
5059 FN_GLOBAL_BOOL(lp_winbind_offline_logon, &Globals.bWinbindOfflineLogon)
5060 FN_GLOBAL_BOOL(lp_winbind_normalize_names, &Globals.bWinbindNormalizeNames)
5061 FN_GLOBAL_BOOL(lp_winbind_rpc_only, &Globals.bWinbindRpcOnly)
5062
5063 FN_GLOBAL_LIST(lp_idmap_domains, &Globals.szIdmapDomains)
5064 FN_GLOBAL_LIST(lp_idmap_backend, &Globals.szIdmapBackend) /* deprecated */
5065 FN_GLOBAL_STRING(lp_idmap_alloc_backend, &Globals.szIdmapAllocBackend)
5066 FN_GLOBAL_INTEGER(lp_idmap_cache_time, &Globals.iIdmapCacheTime)
5067 FN_GLOBAL_INTEGER(lp_idmap_negative_cache_time, &Globals.iIdmapNegativeCacheTime)
5068 FN_GLOBAL_INTEGER(lp_keepalive, &Globals.iKeepalive)
5069 FN_GLOBAL_BOOL(lp_passdb_expand_explicit, &Globals.bPassdbExpandExplicit)
5070
5071 FN_GLOBAL_STRING(lp_ldap_suffix, &Globals.szLdapSuffix)
5072 FN_GLOBAL_STRING(lp_ldap_admin_dn, &Globals.szLdapAdminDn)
5073 FN_GLOBAL_INTEGER(lp_ldap_ssl, &Globals.ldap_ssl)
5074 FN_GLOBAL_INTEGER(lp_ldap_passwd_sync, &Globals.ldap_passwd_sync)
5075 FN_GLOBAL_BOOL(lp_ldap_delete_dn, &Globals.ldap_delete_dn)
5076 FN_GLOBAL_INTEGER(lp_ldap_replication_sleep, &Globals.ldap_replication_sleep)
5077 FN_GLOBAL_INTEGER(lp_ldap_timeout, &Globals.ldap_timeout)
5078 FN_GLOBAL_INTEGER(lp_ldap_page_size, &Globals.ldap_page_size)
5079 FN_GLOBAL_INTEGER(lp_ldap_debug_level, &Globals.ldap_debug_level)
5080 FN_GLOBAL_INTEGER(lp_ldap_debug_threshold, &Globals.ldap_debug_threshold)
5081 FN_GLOBAL_STRING(lp_add_share_cmd, &Globals.szAddShareCommand)
5082 FN_GLOBAL_STRING(lp_change_share_cmd, &Globals.szChangeShareCommand)
5083 FN_GLOBAL_STRING(lp_delete_share_cmd, &Globals.szDeleteShareCommand)
5084 FN_GLOBAL_STRING(lp_usershare_path, &Globals.szUsersharePath)
5085 FN_GLOBAL_LIST(lp_usershare_prefix_allow_list, &Globals.szUsersharePrefixAllowList)
5086 FN_GLOBAL_LIST(lp_usershare_prefix_deny_list, &Globals.szUsersharePrefixDenyList)
5087
5088 FN_GLOBAL_LIST(lp_eventlog_list, &Globals.szEventLogs)
5089
5090 FN_GLOBAL_BOOL(lp_registry_shares, &Globals.bRegistryShares)
5091 FN_GLOBAL_BOOL(lp_usershare_allow_guests, &Globals.bUsershareAllowGuests)
5092 FN_GLOBAL_BOOL(lp_usershare_owner_only, &Globals.bUsershareOwnerOnly)
5093 FN_GLOBAL_BOOL(lp_disable_netbios, &Globals.bDisableNetbios)
5094 FN_GLOBAL_BOOL(lp_reset_on_zero_vc, &Globals.bResetOnZeroVC)
5095 FN_GLOBAL_BOOL(lp_ms_add_printer_wizard, &Globals.bMsAddPrinterWizard)
5096 FN_GLOBAL_BOOL(lp_dns_proxy, &Globals.bDNSproxy)
5097 FN_GLOBAL_BOOL(lp_wins_support, &Globals.bWINSsupport)
5098 FN_GLOBAL_BOOL(lp_we_are_a_wins_server, &Globals.bWINSsupport)
5099 FN_GLOBAL_BOOL(lp_wins_proxy, &Globals.bWINSproxy)
5100 FN_GLOBAL_BOOL(lp_local_master, &Globals.bLocalMaster)
5101 FN_GLOBAL_BOOL(lp_domain_logons, &Globals.bDomainLogons)
5102 FN_GLOBAL_BOOL(lp_load_printers, &Globals.bLoadPrinters)
5103 FN_GLOBAL_BOOL(lp_readraw, &Globals.bReadRaw)
5104 FN_GLOBAL_BOOL(lp_large_readwrite, &Globals.bLargeReadwrite)
5105 FN_GLOBAL_BOOL(lp_writeraw, &Globals.bWriteRaw)
5106 FN_GLOBAL_BOOL(lp_null_passwords, &Globals.bNullPasswords)
5107 FN_GLOBAL_BOOL(lp_obey_pam_restrictions, &Globals.bObeyPamRestrictions)
5108 FN_GLOBAL_BOOL(lp_encrypted_passwords, &Globals.bEncryptPasswords)
5109 FN_GLOBAL_BOOL(lp_update_encrypted, &Globals.bUpdateEncrypt)
5110 FN_GLOBAL_INTEGER(lp_client_schannel, &Globals.clientSchannel)
5111 FN_GLOBAL_INTEGER(lp_server_schannel, &Globals.serverSchannel)
5112 FN_GLOBAL_BOOL(lp_syslog_only, &Globals.bSyslogOnly)
5113 FN_GLOBAL_BOOL(lp_timestamp_logs, &Globals.bTimestampLogs)
5114 FN_GLOBAL_BOOL(lp_debug_prefix_timestamp, &Globals.bDebugPrefixTimestamp)
5115 FN_GLOBAL_BOOL(lp_debug_hires_timestamp, &Globals.bDebugHiresTimestamp)
5116 FN_GLOBAL_BOOL(lp_debug_pid, &Globals.bDebugPid)
5117 FN_GLOBAL_BOOL(lp_debug_uid, &Globals.bDebugUid)
5118 FN_GLOBAL_BOOL(lp_debug_class, &Globals.bDebugClass)
5119 FN_GLOBAL_BOOL(lp_enable_core_files, &Globals.bEnableCoreFiles)
5120 FN_GLOBAL_BOOL(lp_browse_list, &Globals.bBrowseList)
5121 FN_GLOBAL_BOOL(lp_nis_home_map, &Globals.bNISHomeMap)
5122 static FN_GLOBAL_BOOL(lp_time_server, &Globals.bTimeServer)
5123 FN_GLOBAL_BOOL(lp_bind_interfaces_only, &Globals.bBindInterfacesOnly)
5124 FN_GLOBAL_BOOL(lp_pam_password_change, &Globals.bPamPasswordChange)
5125 FN_GLOBAL_BOOL(lp_unix_password_sync, &Globals.bUnixPasswdSync)
5126 FN_GLOBAL_BOOL(lp_passwd_chat_debug, &Globals.bPasswdChatDebug)
5127 FN_GLOBAL_INTEGER(lp_passwd_chat_timeout, &Globals.iPasswdChatTimeout)
5128 FN_GLOBAL_BOOL(lp_nt_pipe_support, &Globals.bNTPipeSupport)
5129 FN_GLOBAL_BOOL(lp_nt_status_support, &Globals.bNTStatusSupport)
5130 FN_GLOBAL_BOOL(lp_stat_cache, &Globals.bStatCache)
5131 FN_GLOBAL_INTEGER(lp_max_stat_cache_size, &Globals.iMaxStatCacheSize)
5132 FN_GLOBAL_BOOL(lp_allow_trusted_domains, &Globals.bAllowTrustedDomains)
5133 FN_GLOBAL_INTEGER(lp_restrict_anonymous, &Globals.restrict_anonymous)
5134 FN_GLOBAL_BOOL(lp_lanman_auth, &Globals.bLanmanAuth)
5135 FN_GLOBAL_BOOL(lp_ntlm_auth, &Globals.bNTLMAuth)
5136 FN_GLOBAL_BOOL(lp_client_plaintext_auth, &Globals.bClientPlaintextAuth)
5137 FN_GLOBAL_BOOL(lp_client_lanman_auth, &Globals.bClientLanManAuth)
5138 FN_GLOBAL_BOOL(lp_client_ntlmv2_auth, &Globals.bClientNTLMv2Auth)
5139 FN_GLOBAL_BOOL(lp_host_msdfs, &Globals.bHostMSDfs)
5140 FN_GLOBAL_BOOL(lp_kernel_oplocks, &Globals.bKernelOplocks)
5141 FN_GLOBAL_BOOL(lp_enhanced_browsing, &Globals.enhanced_browsing)
5142 FN_GLOBAL_BOOL(lp_use_mmap, &Globals.bUseMmap)
5143 FN_GLOBAL_BOOL(lp_unix_extensions, &Globals.bUnixExtensions)
5144 FN_GLOBAL_BOOL(lp_use_spnego, &Globals.bUseSpnego)
5145 FN_GLOBAL_BOOL(lp_client_use_spnego, &Globals.bClientUseSpnego)
5146 FN_GLOBAL_BOOL(lp_hostname_lookups, &Globals.bHostnameLookups)
5147 FN_LOCAL_PARM_BOOL(lp_change_notify, bChangeNotify)
5148 FN_LOCAL_PARM_BOOL(lp_kernel_change_notify, bKernelChangeNotify)
5149 FN_GLOBAL_BOOL(lp_use_kerberos_keytab, &Globals.bUseKerberosKeytab)
5150 FN_GLOBAL_BOOL(lp_defer_sharing_violations, &Globals.bDeferSharingViolations)
5151 FN_GLOBAL_BOOL(lp_enable_privileges, &Globals.bEnablePrivileges)
5152 FN_GLOBAL_BOOL(lp_enable_asu_support, &Globals.bASUSupport)
5153 FN_GLOBAL_INTEGER(lp_os_level, &Globals.os_level)
5154 FN_GLOBAL_INTEGER(lp_max_ttl, &Globals.max_ttl)
5155 FN_GLOBAL_INTEGER(lp_max_wins_ttl, &Globals.max_wins_ttl)
5156 FN_GLOBAL_INTEGER(lp_min_wins_ttl, &Globals.min_wins_ttl)
5157 FN_GLOBAL_INTEGER(lp_max_log_size, &Globals.max_log_size)
5158 FN_GLOBAL_INTEGER(lp_max_open_files, &Globals.max_open_files)
5159 FN_GLOBAL_INTEGER(lp_open_files_db_hash_size, &Globals.open_files_db_hash_size)
5160 FN_GLOBAL_INTEGER(lp_maxxmit, &Globals.max_xmit)
5161 FN_GLOBAL_INTEGER(lp_maxmux, &Globals.max_mux)
5162 FN_GLOBAL_INTEGER(lp_passwordlevel, &Globals.pwordlevel)
5163 FN_GLOBAL_INTEGER(lp_usernamelevel, &Globals.unamelevel)
5164 FN_GLOBAL_INTEGER(lp_deadtime, &Globals.deadtime)
5165 FN_GLOBAL_BOOL(lp_getwd_cache, &Globals.getwd_cache)
5166 FN_GLOBAL_INTEGER(lp_maxprotocol, &Globals.maxprotocol)
5167 FN_GLOBAL_INTEGER(lp_minprotocol, &Globals.minprotocol)
5168 FN_GLOBAL_INTEGER(lp_security, &Globals.security)
5169 FN_GLOBAL_LIST(lp_auth_methods, &Globals.AuthMethods)
5170 FN_GLOBAL_BOOL(lp_paranoid_server_security, &Globals.paranoid_server_security)
5171 FN_GLOBAL_INTEGER(lp_maxdisksize, &Globals.maxdisksize)
5172 FN_GLOBAL_INTEGER(lp_lpqcachetime, &Globals.lpqcachetime)
5173 FN_GLOBAL_INTEGER(lp_max_smbd_processes, &Globals.iMaxSmbdProcesses)
5174 FN_GLOBAL_BOOL(_lp_disable_spoolss, &Globals.bDisableSpoolss)
5175 FN_GLOBAL_INTEGER(lp_syslog, &Globals.syslog)
5176 static FN_GLOBAL_INTEGER(lp_announce_as, &Globals.announce_as)
5177 FN_GLOBAL_INTEGER(lp_lm_announce, &Globals.lm_announce)
5178 FN_GLOBAL_INTEGER(lp_lm_interval, &Globals.lm_interval)
5179 FN_GLOBAL_INTEGER(lp_machine_password_timeout, &Globals.machine_password_timeout)
5180 FN_GLOBAL_INTEGER(lp_map_to_guest, &Globals.map_to_guest)
5181 FN_GLOBAL_INTEGER(lp_oplock_break_wait_time, &Globals.oplock_break_wait_time)
5182 FN_GLOBAL_INTEGER(lp_lock_spin_time, &Globals.iLockSpinTime)
5183 FN_GLOBAL_INTEGER(lp_usershare_max_shares, &Globals.iUsershareMaxShares)
5184 FN_GLOBAL_CONST_STRING(lp_socket_options, &Globals.szSocketOptions)
5185 FN_GLOBAL_INTEGER(lp_config_backend, &Globals.ConfigBackend)
5186
5187 FN_LOCAL_STRING(lp_preexec, szPreExec)
5188 FN_LOCAL_STRING(lp_postexec, szPostExec)
5189 FN_LOCAL_STRING(lp_rootpreexec, szRootPreExec)
5190 FN_LOCAL_STRING(lp_rootpostexec, szRootPostExec)
5191 FN_LOCAL_STRING(lp_servicename, szService)
5192 FN_LOCAL_CONST_STRING(lp_const_servicename, szService)
5193 FN_LOCAL_STRING(lp_pathname, szPath)
5194 FN_LOCAL_STRING(lp_dontdescend, szDontdescend)
5195 FN_LOCAL_STRING(lp_username, szUsername)
5196 FN_LOCAL_LIST(lp_invalid_users, szInvalidUsers)
5197 FN_LOCAL_LIST(lp_valid_users, szValidUsers)
5198 FN_LOCAL_LIST(lp_admin_users, szAdminUsers)
5199 FN_GLOBAL_LIST(lp_svcctl_list, &Globals.szServicesList)
5200 FN_LOCAL_STRING(lp_cups_options, szCupsOptions)
5201 FN_GLOBAL_STRING(lp_cups_server, &Globals.szCupsServer)
5202 FN_GLOBAL_STRING(lp_iprint_server, &Globals.szIPrintServer)
5203 FN_GLOBAL_CONST_STRING(lp_ctdbd_socket, &Globals.ctdbdSocket)
5204 FN_GLOBAL_LIST(lp_cluster_addresses, &Globals.szClusterAddresses)
5205 FN_GLOBAL_BOOL(lp_clustering, &Globals.clustering)
5206 FN_LOCAL_STRING(lp_printcommand, szPrintcommand)
5207 FN_LOCAL_STRING(lp_lpqcommand, szLpqcommand)
5208 FN_LOCAL_STRING(lp_lprmcommand, szLprmcommand)
5209 FN_LOCAL_STRING(lp_lppausecommand, szLppausecommand)
5210 FN_LOCAL_STRING(lp_lpresumecommand, szLpresumecommand)
5211 FN_LOCAL_STRING(lp_queuepausecommand, szQueuepausecommand)
5212 FN_LOCAL_STRING(lp_queueresumecommand, szQueueresumecommand)
5213 static FN_LOCAL_STRING(_lp_printername, szPrintername)
5214 FN_LOCAL_CONST_STRING(lp_printjob_username, szPrintjobUsername)
5215 FN_LOCAL_LIST(lp_hostsallow, szHostsallow)
5216 FN_LOCAL_LIST(lp_hostsdeny, szHostsdeny)
5217 FN_LOCAL_STRING(lp_magicscript, szMagicScript)
5218 FN_LOCAL_STRING(lp_magicoutput, szMagicOutput)
5219 FN_LOCAL_STRING(lp_comment, comment)
5220 FN_LOCAL_STRING(lp_force_user, force_user)
5221 FN_LOCAL_STRING(lp_force_group, force_group)
5222 FN_LOCAL_LIST(lp_readlist, readlist)
5223 FN_LOCAL_LIST(lp_writelist, writelist)
5224 FN_LOCAL_LIST(lp_printer_admin, printer_admin)
5225 FN_LOCAL_STRING(lp_fstype, fstype)
5226 FN_LOCAL_LIST(lp_vfs_objects, szVfsObjects)
5227 FN_LOCAL_STRING(lp_msdfs_proxy, szMSDfsProxy)
5228 static FN_LOCAL_STRING(lp_volume, volume)
5229 FN_LOCAL_STRING(lp_veto_files, szVetoFiles)
5230 FN_LOCAL_STRING(lp_hide_files, szHideFiles)
5231 FN_LOCAL_STRING(lp_veto_oplocks, szVetoOplockFiles)
5232 FN_LOCAL_BOOL(lp_msdfs_root, bMSDfsRoot)
5233 FN_LOCAL_STRING(lp_aio_write_behind, szAioWriteBehind)
5234 FN_LOCAL_STRING(lp_dfree_command, szDfree)
5235 FN_LOCAL_BOOL(lp_autoloaded, autoloaded)
5236 FN_LOCAL_BOOL(lp_preexec_close, bPreexecClose)
5237 FN_LOCAL_BOOL(lp_rootpreexec_close, bRootpreexecClose)
5238 FN_LOCAL_INTEGER(lp_casesensitive, iCaseSensitive)
5239 FN_LOCAL_BOOL(lp_preservecase, bCasePreserve)
5240 FN_LOCAL_BOOL(lp_shortpreservecase, bShortCasePreserve)
5241 FN_LOCAL_BOOL(lp_hide_dot_files, bHideDotFiles)
5242 FN_LOCAL_BOOL(lp_hide_special_files, bHideSpecialFiles)
5243 FN_LOCAL_BOOL(lp_hideunreadable, bHideUnReadable)
5244 FN_LOCAL_BOOL(lp_hideunwriteable_files, bHideUnWriteableFiles)
5245 FN_LOCAL_BOOL(lp_browseable, bBrowseable)
5246 FN_LOCAL_BOOL(lp_readonly, bRead_only)
5247 FN_LOCAL_BOOL(lp_no_set_dir, bNo_set_dir)
5248 FN_LOCAL_BOOL(lp_guest_ok, bGuest_ok)
5249 FN_LOCAL_BOOL(lp_guest_only, bGuest_only)
5250 FN_LOCAL_BOOL(lp_administrative_share, bAdministrative_share)
5251 FN_LOCAL_BOOL(lp_print_ok, bPrint_ok)
5252 FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
5253 FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
5254 FN_LOCAL_BOOL(lp_store_dos_attributes, bStoreDosAttributes)
5255 FN_LOCAL_BOOL(lp_dmapi_support, bDmapiSupport)
5256 FN_LOCAL_PARM_BOOL(lp_locking, bLocking)
5257 FN_LOCAL_PARM_INTEGER(lp_strict_locking, iStrictLocking)
5258 FN_LOCAL_PARM_BOOL(lp_posix_locking, bPosixLocking)
5259 FN_LOCAL_BOOL(lp_share_modes, bShareModes)
5260 FN_LOCAL_BOOL(lp_oplocks, bOpLocks)
5261 FN_LOCAL_BOOL(lp_level2_oplocks, bLevel2OpLocks)
5262 FN_LOCAL_BOOL(lp_onlyuser, bOnlyUser)
5263 FN_LOCAL_PARM_BOOL(lp_manglednames, bMangledNames)
5264 FN_LOCAL_BOOL(lp_widelinks, bWidelinks)
5265 FN_LOCAL_BOOL(lp_symlinks, bSymlinks)
5266 FN_LOCAL_BOOL(lp_syncalways, bSyncAlways)
5267 FN_LOCAL_BOOL(lp_strict_allocate, bStrictAllocate)
5268 FN_LOCAL_BOOL(lp_strict_sync, bStrictSync)
5269 FN_LOCAL_BOOL(lp_map_system, bMap_system)
5270 FN_LOCAL_BOOL(lp_delete_readonly, bDeleteReadonly)
5271 FN_LOCAL_BOOL(lp_fake_oplocks, bFakeOplocks)
5272 FN_LOCAL_BOOL(lp_recursive_veto_delete, bDeleteVetoFiles)
5273 FN_LOCAL_BOOL(lp_dos_filemode, bDosFilemode)
5274 FN_LOCAL_BOOL(lp_dos_filetimes, bDosFiletimes)
5275 FN_LOCAL_BOOL(lp_dos_filetime_resolution, bDosFiletimeResolution)
5276 FN_LOCAL_BOOL(lp_fake_dir_create_times, bFakeDirCreateTimes)
5277 FN_LOCAL_BOOL(lp_blocking_locks, bBlockingLocks)
5278 FN_LOCAL_BOOL(lp_inherit_perms, bInheritPerms)
5279 FN_LOCAL_BOOL(lp_inherit_acls, bInheritACLS)
5280 FN_LOCAL_BOOL(lp_inherit_owner, bInheritOwner)
5281 FN_LOCAL_BOOL(lp_use_client_driver, bUseClientDriver)
5282 FN_LOCAL_BOOL(lp_default_devmode, bDefaultDevmode)
5283 FN_LOCAL_BOOL(lp_force_printername, bForcePrintername)
5284 FN_LOCAL_BOOL(lp_nt_acl_support, bNTAclSupport)
5285 FN_LOCAL_BOOL(lp_force_unknown_acl_user, bForceUnknownAclUser)
5286 FN_LOCAL_BOOL(lp_ea_support, bEASupport)
5287 FN_LOCAL_BOOL(_lp_use_sendfile, bUseSendfile)
5288 FN_LOCAL_BOOL(lp_profile_acls, bProfileAcls)
5289 FN_LOCAL_BOOL(lp_map_acl_inherit, bMap_acl_inherit)
5290 FN_LOCAL_BOOL(lp_afs_share, bAfs_Share)
5291 FN_LOCAL_BOOL(lp_acl_check_permissions, bAclCheckPermissions)
5292 FN_LOCAL_BOOL(lp_acl_group_control, bAclGroupControl)
5293 FN_LOCAL_BOOL(lp_acl_map_full_control, bAclMapFullControl)
5294 FN_LOCAL_INTEGER(lp_create_mask, iCreate_mask)
5295 FN_LOCAL_INTEGER(lp_force_create_mode, iCreate_force_mode)
5296 FN_LOCAL_INTEGER(lp_security_mask, iSecurity_mask)
5297 FN_LOCAL_INTEGER(lp_force_security_mode, iSecurity_force_mode)
5298 FN_LOCAL_INTEGER(lp_dir_mask, iDir_mask)
5299 FN_LOCAL_INTEGER(lp_force_dir_mode, iDir_force_mode)
5300 FN_LOCAL_INTEGER(lp_dir_security_mask, iDir_Security_mask)
5301 FN_LOCAL_INTEGER(lp_force_dir_security_mode, iDir_Security_force_mode)
5302 FN_LOCAL_INTEGER(lp_max_connections, iMaxConnections)
5303 FN_LOCAL_INTEGER(lp_defaultcase, iDefaultCase)
5304 FN_LOCAL_INTEGER(lp_minprintspace, iMinPrintSpace)
5305 FN_LOCAL_INTEGER(lp_printing, iPrinting)
5306 FN_LOCAL_INTEGER(lp_max_reported_jobs, iMaxReportedPrintJobs)
5307 FN_LOCAL_INTEGER(lp_oplock_contention_limit, iOplockContentionLimit)
5308 FN_LOCAL_INTEGER(lp_csc_policy, iCSCPolicy)
5309 FN_LOCAL_INTEGER(lp_write_cache_size, iWriteCacheSize)
5310 FN_LOCAL_INTEGER(lp_block_size, iBlock_size)
5311 FN_LOCAL_INTEGER(lp_dfree_cache_time, iDfreeCacheTime)
5312 FN_LOCAL_INTEGER(lp_allocation_roundup_size, iallocation_roundup_size)
5313 FN_LOCAL_INTEGER(lp_aio_read_size, iAioReadSize)
5314 FN_LOCAL_INTEGER(lp_aio_write_size, iAioWriteSize)
5315 FN_LOCAL_INTEGER(lp_map_readonly, iMap_readonly)
5316 FN_LOCAL_INTEGER(lp_directory_name_cache_size, iDirectoryNameCacheSize)
5317 FN_LOCAL_INTEGER(lp_smb_encrypt, ismb_encrypt)
5318 FN_LOCAL_CHAR(lp_magicchar, magic_char)
5319 FN_GLOBAL_INTEGER(lp_winbind_cache_time, &Globals.winbind_cache_time)
5320 FN_GLOBAL_LIST(lp_winbind_nss_info, &Globals.szWinbindNssInfo)
5321 FN_GLOBAL_INTEGER(lp_algorithmic_rid_base, &Globals.AlgorithmicRidBase)
5322 FN_GLOBAL_INTEGER(lp_name_cache_timeout, &Globals.name_cache_timeout)
5323 FN_GLOBAL_INTEGER(lp_client_signing, &Globals.client_signing)
5324 FN_GLOBAL_INTEGER(lp_server_signing, &Globals.server_signing)
5325 FN_GLOBAL_INTEGER(lp_client_ldap_sasl_wrapping, &Globals.client_ldap_sasl_wrapping)
5326
5327 /* local prototypes */
5328
5329 static int map_parameter(const char *pszParmName);
5330 static int map_parameter_canonical(const char *pszParmName, bool *inverse);
5331 static bool set_boolean(bool *pb, const char *pszParmValue);
5332 static const char *get_boolean(bool bool_value);
5333 static int getservicebyname(const char *pszServiceName,
5334                             struct service *pserviceDest);
5335 static void copy_service(struct service *pserviceDest,
5336                          struct service *pserviceSource,
5337                          struct bitmap *pcopymapDest);
5338 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
5339                          void *userdata);
5340 static bool do_section(const char *pszSectionName, void *userdata);
5341 static void init_copymap(struct service *pservice);
5342 static bool hash_a_service(const char *name, int number);
5343 static void free_service_byindex(int iService);
5344 static char * canonicalize_servicename(const char *name);
5345 static void show_parameter(int parmIndex);
5346 static bool is_synonym_of(int parm1, int parm2, bool *inverse);
5347
5348 /* This is a helper function for parametrical options support. */
5349 /* It returns a pointer to parametrical option value if it exists or NULL otherwise */
5350 /* Actual parametrical functions are quite simple */
5351 static param_opt_struct *get_parametrics(int snum, const char *type, const char *option)
5352 {
5353         bool global_section = False;
5354         char* param_key;
5355         param_opt_struct *data;
5356         
5357         if (snum >= iNumServices) return NULL;
5358         
5359         if (snum < 0) { 
5360                 data = Globals.param_opt;
5361                 global_section = True;
5362         } else {
5363                 data = ServicePtrs[snum]->param_opt;
5364         }
5365     
5366         if (asprintf(&param_key, "%s:%s", type, option) == -1) {
5367                 DEBUG(0,("asprintf failed!\n"));
5368                 return NULL;
5369         }
5370
5371         while (data) {
5372                 if (strcmp(data->key, param_key) == 0) {
5373                         string_free(&param_key);
5374                         return data;
5375                 }
5376                 data = data->next;
5377         }
5378
5379         if (!global_section) {
5380                 /* Try to fetch the same option but from globals */
5381                 /* but only if we are not already working with Globals */
5382                 data = Globals.param_opt;
5383                 while (data) {
5384                         if (strcmp(data->key, param_key) == 0) {
5385                                 string_free(&param_key);
5386                                 return data;
5387                         }
5388                         data = data->next;
5389                 }
5390         }
5391
5392         string_free(&param_key);
5393         
5394         return NULL;
5395 }
5396
5397
5398 #define MISSING_PARAMETER(name) \
5399     DEBUG(0, ("%s(): value is NULL or empty!\n", #name))
5400
5401 /*******************************************************************
5402 convenience routine to return int parameters.
5403 ********************************************************************/
5404 static int lp_int(const char *s)
5405 {
5406
5407         if (!s || !*s) {
5408                 MISSING_PARAMETER(lp_int);
5409                 return (-1);
5410         }
5411
5412         return (int)strtol(s, NULL, 0);
5413 }
5414
5415 /*******************************************************************
5416 convenience routine to return unsigned long parameters.
5417 ********************************************************************/
5418 static unsigned long lp_ulong(const char *s)
5419 {
5420
5421         if (!s || !*s) {
5422                 MISSING_PARAMETER(lp_ulong);
5423                 return (0);
5424         }
5425
5426         return strtoul(s, NULL, 0);
5427 }
5428
5429 /*******************************************************************
5430 convenience routine to return boolean parameters.
5431 ********************************************************************/
5432 static bool lp_bool(const char *s)
5433 {
5434         bool ret = False;
5435
5436         if (!s || !*s) {
5437                 MISSING_PARAMETER(lp_bool);
5438                 return False;
5439         }
5440         
5441         if (!set_boolean(&ret,s)) {
5442                 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
5443                 return False;
5444         }
5445
5446         return ret;
5447 }
5448
5449 /*******************************************************************
5450 convenience routine to return enum parameters.
5451 ********************************************************************/
5452 static int lp_enum(const char *s,const struct enum_list *_enum)
5453 {
5454         int i;
5455
5456         if (!s || !*s || !_enum) {
5457                 MISSING_PARAMETER(lp_enum);
5458                 return (-1);
5459         }
5460         
5461         for (i=0; _enum[i].name; i++) {
5462                 if (strequal(_enum[i].name,s))
5463                         return _enum[i].value;
5464         }
5465
5466         DEBUG(0,("lp_enum(%s,enum): value is not in enum_list!\n",s));
5467         return (-1);
5468 }
5469
5470 #undef MISSING_PARAMETER
5471
5472 /* DO NOT USE lp_parm_string ANYMORE!!!!
5473  * use lp_parm_const_string or lp_parm_talloc_string
5474  *
5475  * lp_parm_string is only used to let old modules find this symbol
5476  */
5477 #undef lp_parm_string
5478  char *lp_parm_string(const char *servicename, const char *type, const char *option);
5479  char *lp_parm_string(const char *servicename, const char *type, const char *option)
5480 {
5481         return lp_parm_talloc_string(lp_servicenumber(servicename), type, option, NULL);
5482 }
5483
5484 /* Return parametric option from a given service. Type is a part of option before ':' */
5485 /* Parametric option has following syntax: 'Type: option = value' */
5486 /* the returned value is talloced on the talloc_tos() */
5487 char *lp_parm_talloc_string(int snum, const char *type, const char *option, const char *def)
5488 {
5489         param_opt_struct *data = get_parametrics(snum, type, option);
5490         
5491         if (data == NULL||data->value==NULL) {
5492                 if (def) {
5493                         return lp_string(def);
5494                 } else {
5495                         return NULL;
5496                 }
5497         }
5498
5499         return lp_string(data->value);
5500 }
5501
5502 /* Return parametric option from a given service. Type is a part of option before ':' */
5503 /* Parametric option has following syntax: 'Type: option = value' */
5504 const char *lp_parm_const_string(int snum, const char *type, const char *option, const char *def)
5505 {
5506         param_opt_struct *data = get_parametrics(snum, type, option);
5507         
5508         if (data == NULL||data->value==NULL)
5509                 return def;
5510                 
5511         return data->value;
5512 }
5513
5514 /* Return parametric option from a given service. Type is a part of option before ':' */
5515 /* Parametric option has following syntax: 'Type: option = value' */
5516
5517 const char **lp_parm_string_list(int snum, const char *type, const char *option, const char **def)
5518 {
5519         param_opt_struct *data = get_parametrics(snum, type, option);
5520
5521         if (data == NULL||data->value==NULL)
5522                 return (const char **)def;
5523                 
5524         if (data->list==NULL) {
5525                 data->list = str_list_make(NULL, data->value, NULL);
5526         }
5527
5528         return (const char **)data->list;
5529 }
5530
5531 /* Return parametric option from a given service. Type is a part of option before ':' */
5532 /* Parametric option has following syntax: 'Type: option = value' */
5533
5534 int lp_parm_int(int snum, const char *type, const char *option, int def)
5535 {
5536         param_opt_struct *data = get_parametrics(snum, type, option);
5537         
5538         if (data && data->value && *data->value)
5539                 return lp_int(data->value);
5540
5541         return def;
5542 }
5543
5544 /* Return parametric option from a given service. Type is a part of option before ':' */
5545 /* Parametric option has following syntax: 'Type: option = value' */
5546
5547 unsigned long lp_parm_ulong(int snum, const char *type, const char *option, unsigned long def)
5548 {
5549         param_opt_struct *data = get_parametrics(snum, type, option);
5550         
5551         if (data && data->value && *data->value)
5552                 return lp_ulong(data->value);
5553
5554         return def;
5555 }
5556
5557 /* Return parametric option from a given service. Type is a part of option before ':' */
5558 /* Parametric option has following syntax: 'Type: option = value' */
5559
5560 bool lp_parm_bool(int snum, const char *type, const char *option, bool def)
5561 {
5562         param_opt_struct *data = get_parametrics(snum, type, option);
5563         
5564         if (data && data->value && *data->value)
5565                 return lp_bool(data->value);
5566
5567         return def;
5568 }
5569
5570 /* Return parametric option from a given service. Type is a part of option before ':' */
5571 /* Parametric option has following syntax: 'Type: option = value' */
5572
5573 int lp_parm_enum(int snum, const char *type, const char *option,
5574                  const struct enum_list *_enum, int def)
5575 {
5576         param_opt_struct *data = get_parametrics(snum, type, option);
5577         
5578         if (data && data->value && *data->value && _enum)
5579                 return lp_enum(data->value, _enum);
5580
5581         return def;
5582 }
5583
5584
5585 /***************************************************************************
5586  Initialise a service to the defaults.
5587 ***************************************************************************/
5588
5589 static void init_service(struct service *pservice)
5590 {
5591         memset((char *)pservice, '\0', sizeof(struct service));
5592         copy_service(pservice, &sDefault, NULL);
5593 }
5594
5595 /***************************************************************************
5596  Free the dynamically allocated parts of a service struct.
5597 ***************************************************************************/
5598
5599 static void free_service(struct service *pservice)
5600 {
5601         int i;
5602         param_opt_struct *data, *pdata;
5603         if (!pservice)
5604                 return;
5605
5606         if (pservice->szService)
5607                 DEBUG(5, ("free_service: Freeing service %s\n",
5608                        pservice->szService));
5609
5610         string_free(&pservice->szService);
5611         bitmap_free(pservice->copymap);
5612
5613         for (i = 0; parm_table[i].label; i++) {
5614                 if ((parm_table[i].type == P_STRING ||
5615                      parm_table[i].type == P_USTRING) &&
5616                     parm_table[i].p_class == P_LOCAL)
5617                         string_free((char **)
5618                                     (((char *)pservice) +
5619                                      PTR_DIFF(parm_table[i].ptr, &sDefault)));
5620                 else if (parm_table[i].type == P_LIST &&
5621                          parm_table[i].p_class == P_LOCAL)
5622                              TALLOC_FREE(*((char ***)
5623                                            (((char *)pservice) +
5624                                             PTR_DIFF(parm_table[i].ptr,
5625                                                      &sDefault))));
5626         }
5627
5628         data = pservice->param_opt;
5629         if (data)
5630                 DEBUG(5,("Freeing parametrics:\n"));
5631         while (data) {
5632                 DEBUG(5,("[%s = %s]\n", data->key, data->value));
5633                 string_free(&data->key);
5634                 string_free(&data->value);
5635                 TALLOC_FREE(data->list);
5636                 pdata = data->next;
5637                 SAFE_FREE(data);
5638                 data = pdata;
5639         }
5640
5641         ZERO_STRUCTP(pservice);
5642 }
5643
5644
5645 /***************************************************************************
5646  remove a service indexed in the ServicePtrs array from the ServiceHash
5647  and free the dynamically allocated parts
5648 ***************************************************************************/
5649
5650 static void free_service_byindex(int idx)
5651 {
5652         if ( !LP_SNUM_OK(idx) ) 
5653                 return;
5654
5655         ServicePtrs[idx]->valid = False;
5656         invalid_services[num_invalid_services++] = idx;
5657
5658         /* we have to cleanup the hash record */
5659
5660         if (ServicePtrs[idx]->szService) {
5661                 char *canon_name = canonicalize_servicename(
5662                         ServicePtrs[idx]->szService );
5663                 
5664                 dbwrap_delete_bystring(ServiceHash, canon_name );
5665                 TALLOC_FREE(canon_name);
5666         }
5667
5668         free_service(ServicePtrs[idx]);
5669 }
5670
5671 /***************************************************************************
5672  Add a new service to the services array initialising it with the given 
5673  service. 
5674 ***************************************************************************/
5675
5676 static int add_a_service(const struct service *pservice, const char *name)
5677 {
5678         int i;
5679         struct service tservice;
5680         int num_to_alloc = iNumServices + 1;
5681         param_opt_struct *data, *pdata;
5682
5683         tservice = *pservice;
5684
5685         /* it might already exist */
5686         if (name) {
5687                 i = getservicebyname(name, NULL);
5688                 if (i >= 0) {
5689                         /* Clean all parametric options for service */
5690                         /* They will be added during parsing again */
5691                         data = ServicePtrs[i]->param_opt;
5692                         while (data) {
5693                                 string_free(&data->key);
5694                                 string_free(&data->value);
5695                                 TALLOC_FREE(data->list);
5696                                 pdata = data->next;
5697                                 SAFE_FREE(data);
5698                                 data = pdata;
5699                         }
5700                         ServicePtrs[i]->param_opt = NULL;
5701                         return (i);
5702                 }
5703         }
5704
5705         /* find an invalid one */
5706         i = iNumServices;
5707         if (num_invalid_services > 0) {
5708                 i = invalid_services[--num_invalid_services];
5709         }
5710
5711         /* if not, then create one */
5712         if (i == iNumServices) {
5713                 struct service **tsp;
5714                 int *tinvalid;
5715                 
5716                 tsp = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(ServicePtrs, struct service *, num_to_alloc);
5717                 if (tsp == NULL) {
5718                         DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
5719                         return (-1);
5720                 }
5721                 ServicePtrs = tsp;
5722                 ServicePtrs[iNumServices] = SMB_MALLOC_P(struct service);
5723                 if (!ServicePtrs[iNumServices]) {
5724                         DEBUG(0,("add_a_service: out of memory!\n"));
5725                         return (-1);
5726                 }
5727                 iNumServices++;
5728
5729                 /* enlarge invalid_services here for now... */
5730                 tinvalid = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(invalid_services, int,
5731                                              num_to_alloc);
5732                 if (tinvalid == NULL) {
5733                         DEBUG(0,("add_a_service: failed to enlarge "
5734                                  "invalid_services!\n"));
5735                         return (-1);
5736                 }
5737                 invalid_services = tinvalid;
5738         } else {
5739                 free_service_byindex(i);
5740         }
5741
5742         ServicePtrs[i]->valid = True;
5743
5744         init_service(ServicePtrs[i]);
5745         copy_service(ServicePtrs[i], &tservice, NULL);
5746         if (name)
5747                 string_set(&ServicePtrs[i]->szService, name);
5748                 
5749         DEBUG(8,("add_a_service: Creating snum = %d for %s\n", 
5750                 i, ServicePtrs[i]->szService));
5751
5752         if (!hash_a_service(ServicePtrs[i]->szService, i)) {
5753                 return (-1);
5754         }
5755                 
5756         return (i);
5757 }
5758
5759 /***************************************************************************
5760   Convert a string to uppercase and remove whitespaces.
5761 ***************************************************************************/
5762
5763 static char *canonicalize_servicename(const char *src)
5764 {
5765         char *result;
5766
5767         if ( !src ) {
5768                 DEBUG(0,("canonicalize_servicename: NULL source name!\n"));
5769                 return NULL;
5770         }
5771
5772         result = talloc_strdup(talloc_tos(), src);
5773         SMB_ASSERT(result != NULL);
5774
5775         strlower_m(result);
5776         return result;
5777 }
5778
5779 /***************************************************************************
5780   Add a name/index pair for the services array to the hash table.
5781 ***************************************************************************/
5782
5783 static bool hash_a_service(const char *name, int idx)
5784 {
5785         char *canon_name;
5786
5787         if ( !ServiceHash ) {
5788                 DEBUG(10,("hash_a_service: creating servicehash\n"));
5789                 ServiceHash = db_open_rbt(NULL);
5790                 if ( !ServiceHash ) {
5791                         DEBUG(0,("hash_a_service: open tdb servicehash failed!\n"));
5792                         return False;
5793                 }
5794         }
5795
5796         DEBUG(10,("hash_a_service: hashing index %d for service name %s\n",
5797                 idx, name));
5798
5799         canon_name = canonicalize_servicename( name );
5800
5801         dbwrap_store_bystring(ServiceHash, canon_name,
5802                               make_tdb_data((uint8 *)&idx, sizeof(idx)),
5803                               TDB_REPLACE);
5804
5805         TALLOC_FREE(canon_name);
5806
5807         return True;
5808 }
5809
5810 /***************************************************************************
5811  Add a new home service, with the specified home directory, defaults coming
5812  from service ifrom.
5813 ***************************************************************************/
5814
5815 bool lp_add_home(const char *pszHomename, int iDefaultService,
5816                  const char *user, const char *pszHomedir)
5817 {
5818         int i;
5819
5820         i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
5821
5822         if (i < 0)
5823                 return (False);
5824
5825         if (!(*(ServicePtrs[iDefaultService]->szPath))
5826             || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(GLOBAL_SECTION_SNUM))) {
5827                 string_set(&ServicePtrs[i]->szPath, pszHomedir);
5828         }
5829
5830         if (!(*(ServicePtrs[i]->comment))) {
5831                 char *comment = NULL;
5832                 if (asprintf(&comment, "Home directory of %s", user) < 0) {
5833                         return false;
5834                 }
5835                 string_set(&ServicePtrs[i]->comment, comment);
5836                 SAFE_FREE(comment);
5837         }
5838
5839         /* set the browseable flag from the global default */
5840
5841         ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
5842
5843         ServicePtrs[i]->autoloaded = True;
5844
5845         DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename, 
5846                user, ServicePtrs[i]->szPath ));
5847
5848         return (True);
5849 }
5850
5851 /***************************************************************************
5852  Add a new service, based on an old one.
5853 ***************************************************************************/
5854
5855 int lp_add_service(const char *pszService, int iDefaultService)
5856 {
5857         if (iDefaultService < 0) {
5858                 return add_a_service(&sDefault, pszService);
5859         }
5860
5861         return (add_a_service(ServicePtrs[iDefaultService], pszService));
5862 }
5863
5864 /***************************************************************************
5865  Add the IPC service.
5866 ***************************************************************************/
5867
5868 static bool lp_add_ipc(const char *ipc_name, bool guest_ok)
5869 {
5870         char *comment = NULL;
5871         int i = add_a_service(&sDefault, ipc_name);
5872
5873         if (i < 0)
5874                 return (False);
5875
5876         if (asprintf(&comment, "IPC Service (%s)",
5877                                 Globals.szServerString) < 0) {
5878                 return (False);
5879         }
5880
5881         string_set(&ServicePtrs[i]->szPath, tmpdir());
5882         string_set(&ServicePtrs[i]->szUsername, "");
5883         string_set(&ServicePtrs[i]->comment, comment);
5884         string_set(&ServicePtrs[i]->fstype, "IPC");
5885         ServicePtrs[i]->iMaxConnections = 0;
5886         ServicePtrs[i]->bAvailable = True;
5887         ServicePtrs[i]->bRead_only = True;
5888         ServicePtrs[i]->bGuest_only = False;
5889         ServicePtrs[i]->bAdministrative_share = True;
5890         ServicePtrs[i]->bGuest_ok = guest_ok;
5891         ServicePtrs[i]->bPrint_ok = False;
5892         ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
5893
5894         DEBUG(3, ("adding IPC service\n"));
5895
5896         SAFE_FREE(comment);
5897         return (True);
5898 }
5899
5900 /***************************************************************************
5901  Add a new printer service, with defaults coming from service iFrom.
5902 ***************************************************************************/
5903
5904 bool lp_add_printer(const char *pszPrintername, int iDefaultService)
5905 {
5906         const char *comment = "From Printcap";
5907         int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
5908
5909         if (i < 0)
5910                 return (False);
5911
5912         /* note that we do NOT default the availability flag to True - */
5913         /* we take it from the default service passed. This allows all */
5914         /* dynamic printers to be disabled by disabling the [printers] */
5915         /* entry (if/when the 'available' keyword is implemented!).    */
5916
5917         /* the printer name is set to the service name. */
5918         string_set(&ServicePtrs[i]->szPrintername, pszPrintername);
5919         string_set(&ServicePtrs[i]->comment, comment);
5920
5921         /* set the browseable flag from the gloabl default */
5922         ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
5923
5924         /* Printers cannot be read_only. */
5925         ServicePtrs[i]->bRead_only = False;
5926         /* No share modes on printer services. */
5927         ServicePtrs[i]->bShareModes = False;
5928         /* No oplocks on printer services. */
5929         ServicePtrs[i]->bOpLocks = False;
5930         /* Printer services must be printable. */
5931         ServicePtrs[i]->bPrint_ok = True;
5932         
5933         DEBUG(3, ("adding printer service %s\n", pszPrintername));
5934
5935         return (True);
5936 }
5937
5938
5939 /***************************************************************************
5940  Check whether the given parameter name is valid.
5941  Parametric options (names containing a colon) are considered valid.
5942 ***************************************************************************/
5943
5944 bool lp_parameter_is_valid(const char *pszParmName)
5945 {
5946         return ((map_parameter(pszParmName) != -1) ||
5947                 (strchr(pszParmName, ':') != NULL));
5948 }
5949
5950 /***************************************************************************
5951  Check whether the given name is the name of a global parameter.
5952  Returns True for strings belonging to parameters of class
5953  P_GLOBAL, False for all other strings, also for parametric options
5954  and strings not belonging to any option.
5955 ***************************************************************************/
5956
5957 bool lp_parameter_is_global(const char *pszParmName)
5958 {
5959         int num = map_parameter(pszParmName);
5960
5961         if (num >= 0) {
5962                 return (parm_table[num].p_class == P_GLOBAL);
5963         }
5964
5965         return False;
5966 }
5967
5968 /**************************************************************************
5969  Check whether the given name is the canonical name of a parameter.
5970  Returns False if it is not a valid parameter Name.
5971  For parametric options, True is returned.
5972 **************************************************************************/
5973
5974 bool lp_parameter_is_canonical(const char *parm_name)
5975 {
5976         if (!lp_parameter_is_valid(parm_name)) {
5977                 return False;
5978         }
5979
5980         return (map_parameter(parm_name) ==
5981                 map_parameter_canonical(parm_name, NULL));
5982 }
5983
5984 /**************************************************************************
5985  Determine the canonical name for a parameter.
5986  Indicate when it is an inverse (boolean) synonym instead of a
5987  "usual" synonym.
5988 **************************************************************************/
5989
5990 bool lp_canonicalize_parameter(const char *parm_name, const char **canon_parm,
5991                                bool *inverse)
5992 {
5993         int num;
5994
5995         if (!lp_parameter_is_valid(parm_name)) {
5996                 *canon_parm = NULL;
5997                 return False;
5998         }
5999
6000         num = map_parameter_canonical(parm_name, inverse);
6001         if (num < 0) {
6002                 /* parametric option */
6003                 *canon_parm = parm_name;
6004         } else {
6005                 *canon_parm = parm_table[num].label;
6006         }
6007
6008         return True;
6009
6010 }
6011
6012 /**************************************************************************
6013  Determine the canonical name for a parameter.
6014  Turn the value given into the inverse boolean expression when
6015  the synonym is an invers boolean synonym.
6016
6017  Return True if parm_name is a valid parameter name and
6018  in case it is an invers boolean synonym, if the val string could
6019  successfully be converted to the reverse bool.
6020  Return false in all other cases.
6021 **************************************************************************/
6022
6023 bool lp_canonicalize_parameter_with_value(const char *parm_name,
6024                                           const char *val,
6025                                           const char **canon_parm,
6026                                           const char **canon_val)
6027 {
6028         int num;
6029         bool inverse;
6030
6031         if (!lp_parameter_is_valid(parm_name)) {
6032                 *canon_parm = NULL;
6033                 *canon_val = NULL;
6034                 return False;
6035         }
6036
6037         num = map_parameter_canonical(parm_name, &inverse);
6038         if (num < 0) {
6039                 /* parametric option */
6040                 *canon_parm = parm_name;
6041                 *canon_val = val;
6042         } else {
6043                 *canon_parm = parm_table[num].label;
6044                 if (inverse) {
6045                         if (!lp_invert_boolean(val, canon_val)) {
6046                                 *canon_val = NULL;
6047                                 return False;
6048                         }
6049                 } else {
6050                         *canon_val = val;
6051                 }
6052         }
6053
6054         return True;
6055 }
6056
6057 /***************************************************************************
6058  Map a parameter's string representation to something we can use. 
6059  Returns False if the parameter string is not recognised, else TRUE.
6060 ***************************************************************************/
6061
6062 static int map_parameter(const char *pszParmName)
6063 {
6064         int iIndex;
6065
6066         if (*pszParmName == '-')
6067                 return (-1);
6068
6069         for (iIndex = 0; parm_table[iIndex].label; iIndex++)
6070                 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
6071                         return (iIndex);
6072
6073         /* Warn only if it isn't parametric option */
6074         if (strchr(pszParmName, ':') == NULL)
6075                 DEBUG(1, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
6076         /* We do return 'fail' for parametric options as well because they are
6077            stored in different storage
6078          */
6079         return (-1);
6080 }
6081
6082 /***************************************************************************
6083  Map a parameter's string representation to the index of the canonical
6084  form of the parameter (it might be a synonym).
6085  Returns -1 if the parameter string is not recognised.
6086 ***************************************************************************/
6087
6088 static int map_parameter_canonical(const char *pszParmName, bool *inverse)
6089 {
6090         int parm_num, canon_num;
6091         bool loc_inverse = False;
6092
6093         parm_num = map_parameter(pszParmName);
6094         if ((parm_num < 0) || !(parm_table[parm_num].flags & FLAG_HIDE)) {
6095                 /* invalid, parametric or no canidate for synonyms ... */
6096                 goto done;
6097         }
6098
6099         for (canon_num = 0; parm_table[canon_num].label; canon_num++) {
6100                 if (is_synonym_of(parm_num, canon_num, &loc_inverse)) {
6101                         parm_num = canon_num;
6102                         goto done;
6103                 }
6104         }
6105
6106 done:
6107         if (inverse != NULL) {
6108                 *inverse = loc_inverse;
6109         }
6110         return parm_num;
6111 }
6112
6113 /***************************************************************************
6114  return true if parameter number parm1 is a synonym of parameter
6115  number parm2 (parm2 being the principal name).
6116  set inverse to True if parm1 is P_BOOLREV and parm2 is P_BOOL,
6117  False otherwise.
6118 ***************************************************************************/
6119
6120 static bool is_synonym_of(int parm1, int parm2, bool *inverse)
6121 {
6122         if ((parm_table[parm1].ptr == parm_table[parm2].ptr) &&
6123             (parm_table[parm1].flags & FLAG_HIDE) &&
6124             !(parm_table[parm2].flags & FLAG_HIDE))
6125         {
6126                 if (inverse != NULL) {
6127                         if ((parm_table[parm1].type == P_BOOLREV) &&
6128                             (parm_table[parm2].type == P_BOOL))
6129                         {
6130                                 *inverse = True;
6131                         } else {
6132                                 *inverse = False;
6133                         }
6134                 }
6135                 return True;
6136         }
6137         return False;
6138 }
6139
6140 /***************************************************************************
6141  Show one parameter's name, type, [values,] and flags.
6142  (helper functions for show_parameter_list)
6143 ***************************************************************************/
6144
6145 static void show_parameter(int parmIndex)
6146 {
6147         int enumIndex, flagIndex;
6148         int parmIndex2;
6149         bool hadFlag;
6150         bool hadSyn;
6151         bool inverse;
6152         const char *type[] = { "P_BOOL", "P_BOOLREV", "P_CHAR", "P_INTEGER",
6153                 "P_OCTAL", "P_LIST", "P_STRING", "P_USTRING",
6154                 "P_ENUM", "P_SEP"};
6155         unsigned flags[] = { FLAG_BASIC, FLAG_SHARE, FLAG_PRINT, FLAG_GLOBAL,
6156                 FLAG_WIZARD, FLAG_ADVANCED, FLAG_DEVELOPER, FLAG_DEPRECATED,
6157                 FLAG_HIDE, FLAG_DOS_STRING};
6158         const char *flag_names[] = { "FLAG_BASIC", "FLAG_SHARE", "FLAG_PRINT",
6159                 "FLAG_GLOBAL", "FLAG_WIZARD", "FLAG_ADVANCED", "FLAG_DEVELOPER",
6160                 "FLAG_DEPRECATED", "FLAG_HIDE", "FLAG_DOS_STRING", NULL};
6161
6162         printf("%s=%s", parm_table[parmIndex].label,
6163                type[parm_table[parmIndex].type]);
6164         if (parm_table[parmIndex].type == P_ENUM) {
6165                 printf(",");
6166                 for (enumIndex=0;
6167                      parm_table[parmIndex].enum_list[enumIndex].name;
6168                      enumIndex++)
6169                 {
6170                         printf("%s%s",
6171                                enumIndex ? "|" : "",
6172                                parm_table[parmIndex].enum_list[enumIndex].name);
6173                 }
6174         }
6175         printf(",");
6176         hadFlag = False;
6177         for (flagIndex=0; flag_names[flagIndex]; flagIndex++) {
6178                 if (parm_table[parmIndex].flags & flags[flagIndex]) {
6179                         printf("%s%s",
6180                                 hadFlag ? "|" : "",
6181                                 flag_names[flagIndex]);
6182                         hadFlag = True;
6183                 }
6184         }
6185
6186         /* output synonyms */
6187         hadSyn = False;
6188         for (parmIndex2=0; parm_table[parmIndex2].label; parmIndex2++) {
6189                 if (is_synonym_of(parmIndex, parmIndex2, &inverse)) {
6190                         printf(" (%ssynonym of %s)", inverse ? "inverse " : "",
6191                                parm_table[parmIndex2].label);
6192                 } else if (is_synonym_of(parmIndex2, parmIndex, &inverse)) {
6193                         if (!hadSyn) {
6194                                 printf(" (synonyms: ");
6195                                 hadSyn = True;
6196                         } else {
6197                                 printf(", ");
6198                         }
6199                         printf("%s%s", parm_table[parmIndex2].label,
6200                                inverse ? "[i]" : "");
6201                 }
6202         }
6203         if (hadSyn) {
6204                 printf(")");
6205         }
6206
6207         printf("\n");
6208 }
6209
6210 /***************************************************************************
6211  Show all parameter's name, type, [values,] and flags.
6212 ***************************************************************************/
6213
6214 void show_parameter_list(void)
6215 {
6216         int classIndex, parmIndex;
6217         const char *section_names[] = { "local", "global", NULL};
6218
6219         for (classIndex=0; section_names[classIndex]; classIndex++) {
6220                 printf("[%s]\n", section_names[classIndex]);
6221                 for (parmIndex = 0; parm_table[parmIndex].label; parmIndex++) {
6222                         if (parm_table[parmIndex].p_class == classIndex) {
6223                                 show_parameter(parmIndex);
6224                         }
6225                 }
6226         }
6227 }
6228
6229 /***************************************************************************
6230  Set a boolean variable from the text value stored in the passed string.
6231  Returns True in success, False if the passed string does not correctly 
6232  represent a boolean.
6233 ***************************************************************************/
6234
6235 static bool set_boolean(bool *pb, const char *pszParmValue)
6236 {
6237         bool bRetval;
6238         bool value;
6239
6240         bRetval = True;
6241         value = False;
6242         if (strwicmp(pszParmValue, "yes") == 0 ||
6243             strwicmp(pszParmValue, "true") == 0 ||
6244             strwicmp(pszParmValue, "1") == 0)
6245                 value = True;
6246         else if (strwicmp(pszParmValue, "no") == 0 ||
6247                     strwicmp(pszParmValue, "False") == 0 ||
6248                     strwicmp(pszParmValue, "0") == 0)
6249                 value = False;
6250         else {
6251                 DEBUG(2,
6252                       ("ERROR: Badly formed boolean in configuration file: \"%s\".\n",
6253                        pszParmValue));
6254                 bRetval = False;
6255         }
6256
6257         if ((pb != NULL) && (bRetval != False)) {
6258                 *pb = value;
6259         }
6260
6261         return (bRetval);
6262 }
6263
6264
6265 /***************************************************************************
6266  Check if a given string correctly represents a boolean value.
6267 ***************************************************************************/
6268
6269 bool lp_string_is_valid_boolean(const char *parm_value)
6270 {
6271         return set_boolean(NULL, parm_value);
6272 }
6273
6274 /***************************************************************************
6275  Get the standard string representation of a boolean value ("yes" or "no")
6276 ***************************************************************************/
6277
6278 static const char *get_boolean(bool bool_value)
6279 {
6280         static const char *yes_str = "yes";
6281         static const char *no_str = "no";
6282
6283         return (bool_value ? yes_str : no_str);
6284 }
6285
6286 /***************************************************************************
6287  Provide the string of the negated boolean value associated to the boolean
6288  given as a string. Returns False if the passed string does not correctly
6289  represent a boolean.
6290 ***************************************************************************/
6291
6292 bool lp_invert_boolean(const char *str, const char **inverse_str)
6293 {
6294         bool val;
6295
6296         if (!set_boolean(&val, str)) {
6297                 return False;
6298         }
6299
6300         *inverse_str = get_boolean(!val);
6301         return True;
6302 }
6303
6304 /***************************************************************************
6305  Provide the canonical string representation of a boolean value given
6306  as a string. Return True on success, False if the string given does
6307  not correctly represent a boolean.
6308 ***************************************************************************/
6309
6310 bool lp_canonicalize_boolean(const char *str, const char**canon_str)
6311 {
6312         bool val;
6313
6314         if (!set_boolean(&val, str)) {
6315                 return False;
6316         }
6317
6318         *canon_str = get_boolean(val);
6319         return True;
6320 }
6321
6322 /***************************************************************************
6323 Find a service by name. Otherwise works like get_service.
6324 ***************************************************************************/
6325
6326 static int getservicebyname(const char *pszServiceName, struct service *pserviceDest)
6327 {
6328         int iService = -1;
6329         char *canon_name;
6330         TDB_DATA data;
6331
6332         if (ServiceHash == NULL) {
6333                 return -1;
6334         }
6335
6336         canon_name = canonicalize_servicename(pszServiceName);
6337
6338         data = dbwrap_fetch_bystring(ServiceHash, canon_name, canon_name);
6339
6340         if ((data.dptr != NULL) && (data.dsize == sizeof(iService))) {
6341                 iService = *(int *)data.dptr;
6342         }
6343
6344         TALLOC_FREE(canon_name);
6345
6346         if ((iService != -1) && (LP_SNUM_OK(iService))
6347             && (pserviceDest != NULL)) {
6348                 copy_service(pserviceDest, ServicePtrs[iService], NULL);
6349         }
6350
6351         return (iService);
6352 }
6353
6354 /***************************************************************************
6355  Copy a service structure to another.
6356  If pcopymapDest is NULL then copy all fields
6357 ***************************************************************************/
6358
6359 static void copy_service(struct service *pserviceDest, struct service *pserviceSource,
6360                          struct bitmap *pcopymapDest)
6361 {
6362         int i;
6363         bool bcopyall = (pcopymapDest == NULL);
6364         param_opt_struct *data, *pdata, *paramo;
6365         bool not_added;
6366
6367         for (i = 0; parm_table[i].label; i++)
6368                 if (parm_table[i].ptr && parm_table[i].p_class == P_LOCAL &&
6369                     (bcopyall || bitmap_query(pcopymapDest,i))) {
6370                         void *def_ptr = parm_table[i].ptr;
6371                         void *src_ptr =
6372                                 ((char *)pserviceSource) + PTR_DIFF(def_ptr,
6373                                                                     &sDefault);
6374                         void *dest_ptr =
6375                                 ((char *)pserviceDest) + PTR_DIFF(def_ptr,
6376                                                                   &sDefault);
6377
6378                         switch (parm_table[i].type) {
6379                                 case P_BOOL:
6380                                 case P_BOOLREV:
6381                                         *(bool *)dest_ptr = *(bool *)src_ptr;
6382                                         break;
6383
6384                                 case P_INTEGER:
6385                                 case P_ENUM:
6386                                 case P_OCTAL:
6387                                         *(int *)dest_ptr = *(int *)src_ptr;
6388                                         break;
6389
6390                                 case P_CHAR:
6391                                         *(char *)dest_ptr = *(char *)src_ptr;
6392                                         break;
6393
6394                                 case P_STRING:
6395                                         string_set((char **)dest_ptr,
6396                                                    *(char **)src_ptr);
6397                                         break;
6398
6399                                 case P_USTRING:
6400                                         string_set((char **)dest_ptr,
6401                                                    *(char **)src_ptr);
6402                                         strupper_m(*(char **)dest_ptr);
6403                                         break;
6404                                 case P_LIST:
6405                                         TALLOC_FREE(*((char ***)dest_ptr));
6406                                         str_list_copy(NULL, (char ***)dest_ptr,
6407                                                       *(const char ***)src_ptr);
6408                                         break;
6409                                 default:
6410                                         break;
6411                         }
6412                 }
6413
6414         if (bcopyall) {
6415                 init_copymap(pserviceDest);
6416                 if (pserviceSource->copymap)
6417                         bitmap_copy(pserviceDest->copymap,
6418                                     pserviceSource->copymap);
6419         }
6420         
6421         data = pserviceSource->param_opt;
6422         while (data) {
6423                 not_added = True;
6424                 pdata = pserviceDest->param_opt;
6425                 /* Traverse destination */
6426                 while (pdata) {
6427                         /* If we already have same option, override it */
6428                         if (strcmp(pdata->key, data->key) == 0) {
6429                                 string_free(&pdata->value);
6430                                 TALLOC_FREE(data->list);
6431                                 pdata->value = SMB_STRDUP(data->value);
6432                                 not_added = False;
6433                                 break;
6434                         }
6435                         pdata = pdata->next;
6436                 }
6437                 if (not_added) {
6438                     paramo = SMB_XMALLOC_P(param_opt_struct);
6439                     paramo->key = SMB_STRDUP(data->key);
6440                     paramo->value = SMB_STRDUP(data->value);
6441                     paramo->list = NULL;
6442                     DLIST_ADD(pserviceDest->param_opt, paramo);
6443                 }
6444                 data = data->next;
6445         }
6446 }
6447
6448 /***************************************************************************
6449 Check a service for consistency. Return False if the service is in any way
6450 incomplete or faulty, else True.
6451 ***************************************************************************/
6452
6453 bool service_ok(int iService)
6454 {
6455         bool bRetval;
6456
6457         bRetval = True;
6458         if (ServicePtrs[iService]->szService[0] == '\0') {
6459                 DEBUG(0, ("The following message indicates an internal error:\n"));
6460                 DEBUG(0, ("No service name in service entry.\n"));
6461                 bRetval = False;
6462         }
6463
6464         /* The [printers] entry MUST be printable. I'm all for flexibility, but */
6465         /* I can't see why you'd want a non-printable printer service...        */
6466         if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
6467                 if (!ServicePtrs[iService]->bPrint_ok) {
6468                         DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
6469                                ServicePtrs[iService]->szService));
6470                         ServicePtrs[iService]->bPrint_ok = True;
6471                 }
6472                 /* [printers] service must also be non-browsable. */
6473                 if (ServicePtrs[iService]->bBrowseable)
6474                         ServicePtrs[iService]->bBrowseable = False;
6475         }
6476
6477         if (ServicePtrs[iService]->szPath[0] == '\0' &&
6478             strwicmp(ServicePtrs[iService]->szService, HOMES_NAME) != 0 &&
6479             ServicePtrs[iService]->szMSDfsProxy[0] == '\0'
6480             ) {
6481                 DEBUG(0, ("WARNING: No path in service %s - making it unavailable!\n",
6482                         ServicePtrs[iService]->szService));
6483                 ServicePtrs[iService]->bAvailable = False;
6484         }
6485
6486         /* If a service is flagged unavailable, log the fact at level 1. */
6487         if (!ServicePtrs[iService]->bAvailable)
6488                 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
6489                           ServicePtrs[iService]->szService));
6490
6491         return (bRetval);
6492 }
6493
6494 /*
6495  * process_registry_globals
6496  */
6497 static bool process_registry_globals(void)
6498 {
6499         WERROR werr;
6500         char **param_names;
6501         char **param_values;
6502         uint32_t num_params;
6503         uint32_t count;
6504         TALLOC_CTX *mem_ctx = talloc_stackframe();
6505         bool ret = false;
6506
6507         if (conf_ctx == NULL) {
6508                 /* first time */
6509                 werr = smbconf_init(NULL, &conf_ctx, "registry:");
6510                 if (!W_ERROR_IS_OK(werr)) {
6511                         goto done;
6512                 }
6513         }
6514
6515         if (!smbconf_share_exists(conf_ctx, GLOBAL_NAME)) {
6516                 /* nothing to read from the registry yet but make sure lp_load
6517                  * doesn't return false */
6518                 ret = true;
6519                 goto done;
6520         }
6521
6522         werr = smbconf_get_share(conf_ctx, mem_ctx, GLOBAL_NAME,
6523                                  &num_params, &param_names, &param_values);
6524         if (!W_ERROR_IS_OK(werr)) {
6525                 goto done;
6526         }
6527
6528         for (count = 0; count < num_params; count++) {
6529                 ret = do_parameter(param_names[count], param_values[count],
6530                                    NULL);
6531                 if (ret != true) {
6532                         goto done;
6533                 }
6534         }
6535
6536         ret = do_parameter("registry shares", "yes", NULL);
6537         /* store the csn */
6538         smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
6539
6540 done:
6541         TALLOC_FREE(mem_ctx);
6542         return ret;
6543 }
6544
6545 static struct file_lists {
6546         struct file_lists *next;
6547         char *name;
6548         char *subfname;
6549         time_t modtime;
6550 } *file_lists = NULL;
6551
6552 /*******************************************************************
6553  Keep a linked list of all config files so we know when one has changed 
6554  it's date and needs to be reloaded.
6555 ********************************************************************/
6556
6557 static void add_to_file_list(const char *fname, const char *subfname)
6558 {
6559         struct file_lists *f = file_lists;
6560
6561         while (f) {
6562                 if (f->name && !strcmp(f->name, fname))
6563                         break;
6564                 f = f->next;
6565         }
6566
6567         if (!f) {
6568                 f = SMB_MALLOC_P(struct file_lists);
6569                 if (!f)
6570                         return;
6571                 f->next = file_lists;
6572                 f->name = SMB_STRDUP(fname);
6573                 if (!f->name) {
6574                         SAFE_FREE(f);
6575                         return;
6576                 }
6577                 f->subfname = SMB_STRDUP(subfname);
6578                 if (!f->subfname) {
6579                         SAFE_FREE(f);
6580                         return;
6581                 }
6582                 file_lists = f;
6583                 f->modtime = file_modtime(subfname);
6584         } else {
6585                 time_t t = file_modtime(subfname);
6586                 if (t)
6587                         f->modtime = t;
6588         }
6589 }
6590
6591 /**
6592  * Utility function for outsiders to check if we're running on registry.
6593  */
6594 bool lp_config_backend_is_registry(void)
6595 {
6596         return (lp_config_backend() == CONFIG_BACKEND_REGISTRY);
6597 }
6598
6599 /**
6600  * Utility function to check if the config backend is FILE.
6601  */
6602 bool lp_config_backend_is_file(void)
6603 {
6604         return (lp_config_backend() == CONFIG_BACKEND_FILE);
6605 }
6606
6607 /*******************************************************************
6608  Check if a config file has changed date.
6609 ********************************************************************/
6610
6611 bool lp_file_list_changed(void)
6612 {
6613         struct file_lists *f = file_lists;
6614
6615         DEBUG(6, ("lp_file_list_changed()\n"));
6616
6617         if (lp_config_backend_is_registry()) {
6618                 if (conf_ctx == NULL) {
6619                         WERROR werr;
6620                         werr = smbconf_init(NULL, &conf_ctx, "registry:");
6621                         if (!W_ERROR_IS_OK(werr)) {
6622                                 DEBUG(0, ("error opening configuration: %s\n",
6623                                           dos_errstr(werr)));
6624                                 return false;
6625                         }
6626                 }
6627                 if (smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL)) {
6628                         DEBUGADD(6, ("registry config changed\n"));
6629                         return true;
6630                 }
6631         }
6632
6633         while (f) {
6634                 char *n2 = NULL;
6635                 time_t mod_time;
6636
6637                 n2 = alloc_sub_basic(get_current_username(),
6638                                     current_user_info.domain,
6639                                     f->name);
6640                 if (!n2) {
6641                         return false;
6642                 }
6643                 DEBUGADD(6, ("file %s -> %s  last mod_time: %s\n",
6644                              f->name, n2, ctime(&f->modtime)));
6645
6646                 mod_time = file_modtime(n2);
6647
6648                 if (mod_time && ((f->modtime != mod_time) || (f->subfname == NULL) || (strcmp(n2, f->subfname) != 0))) {
6649                         DEBUGADD(6,
6650                                  ("file %s modified: %s\n", n2,
6651                                   ctime(&mod_time)));
6652                         f->modtime = mod_time;
6653                         SAFE_FREE(f->subfname);
6654                         f->subfname = n2; /* Passing ownership of
6655                                              return from alloc_sub_basic
6656                                              above. */
6657                         return true;
6658                 }
6659                 SAFE_FREE(n2);
6660                 f = f->next;
6661         }
6662         return (False);
6663 }
6664
6665
6666 /***************************************************************************
6667  Run standard_sub_basic on netbios name... needed because global_myname
6668  is not accessed through any lp_ macro.
6669  Note: We must *NOT* use string_set() here as ptr points to global_myname.
6670 ***************************************************************************/
6671
6672 static bool handle_netbios_name(int snum, const char *pszParmValue, char **ptr)
6673 {
6674         bool ret;
6675         char *netbios_name = alloc_sub_basic(get_current_username(),
6676                                         current_user_info.domain,
6677                                         pszParmValue);
6678
6679         ret = set_global_myname(netbios_name);
6680         SAFE_FREE(netbios_name);
6681         string_set(&Globals.szNetbiosName,global_myname());
6682
6683         DEBUG(4, ("handle_netbios_name: set global_myname to: %s\n",
6684                global_myname()));
6685
6686         return ret;
6687 }
6688
6689 static bool handle_charset(int snum, const char *pszParmValue, char **ptr)
6690 {
6691         if (strcmp(*ptr, pszParmValue) != 0) {
6692                 string_set(ptr, pszParmValue);
6693                 init_iconv();
6694         }
6695         return True;
6696 }
6697
6698
6699
6700 static bool handle_workgroup(int snum, const char *pszParmValue, char **ptr)
6701 {
6702         bool ret;
6703         
6704         ret = set_global_myworkgroup(pszParmValue);
6705         string_set(&Globals.szWorkgroup,lp_workgroup());
6706         
6707         return ret;
6708 }
6709
6710 static bool handle_netbios_scope(int snum, const char *pszParmValue, char **ptr)
6711 {
6712         bool ret;
6713         
6714         ret = set_global_scope(pszParmValue);
6715         string_set(&Globals.szNetbiosScope,global_scope());
6716
6717         return ret;
6718 }
6719
6720 static bool handle_netbios_aliases(int snum, const char *pszParmValue, char **ptr)
6721 {
6722         TALLOC_FREE(Globals.szNetbiosAliases);
6723         Globals.szNetbiosAliases = str_list_make(NULL, pszParmValue, NULL);
6724         return set_netbios_aliases((const char **)Globals.szNetbiosAliases);
6725 }
6726
6727 /***************************************************************************
6728  Handle the include operation.
6729 ***************************************************************************/
6730 static bool bNoIncludes = false;
6731
6732 static bool handle_include(int snum, const char *pszParmValue, char **ptr)
6733 {
6734         char *fname;
6735
6736         if (strequal(pszParmValue, INCLUDE_REGISTRY_NAME)) {
6737                 if (bNoIncludes) {
6738                         return true;
6739                 }
6740                 if (bInGlobalSection) {
6741                         return process_registry_globals();
6742                 } else {
6743                         DEBUG(1, ("\"include = registry\" only effective "
6744                                   "in %s section\n", GLOBAL_NAME));
6745                         return false;
6746                 }
6747         }
6748
6749         fname = alloc_sub_basic(get_current_username(),
6750                                 current_user_info.domain,
6751                                 pszParmValue);
6752
6753         add_to_file_list(pszParmValue, fname);
6754
6755         string_set(ptr, fname);
6756
6757         if (file_exist(fname, NULL)) {
6758                 bool ret = pm_process(fname, do_section, do_parameter, NULL);
6759                 SAFE_FREE(fname);
6760                 return ret;
6761         }
6762
6763         DEBUG(2, ("Can't find include file %s\n", fname));
6764         SAFE_FREE(fname);
6765         return false;
6766 }
6767
6768 /***************************************************************************
6769  Handle the interpretation of the copy parameter.
6770 ***************************************************************************/
6771
6772 static bool handle_copy(int snum, const char *pszParmValue, char **ptr)
6773 {
6774         bool bRetval;
6775         int iTemp;
6776         struct service serviceTemp;
6777
6778         string_set(ptr, pszParmValue);
6779
6780         init_service(&serviceTemp);
6781
6782         bRetval = False;
6783
6784         DEBUG(3, ("Copying service from service %s\n", pszParmValue));
6785
6786         if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
6787                 if (iTemp == iServiceIndex) {
6788                         DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
6789                 } else {
6790                         copy_service(ServicePtrs[iServiceIndex],
6791                                      &serviceTemp,
6792                                      ServicePtrs[iServiceIndex]->copymap);
6793                         bRetval = True;
6794                 }
6795         } else {
6796                 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
6797                 bRetval = False;
6798         }
6799
6800         free_service(&serviceTemp);
6801         return (bRetval);
6802 }
6803
6804 static bool handle_ldap_debug_level(int snum, const char *pszParmValue, char **ptr)
6805 {
6806         Globals.ldap_debug_level = lp_int(pszParmValue);
6807         init_ldap_debugging();
6808         return true;
6809 }
6810
6811 /***************************************************************************
6812  Handle idmap/non unix account uid and gid allocation parameters.  The format of these
6813  parameters is:
6814
6815  [global]
6816
6817         idmap uid = 1000-1999
6818         idmap gid = 700-899
6819
6820  We only do simple parsing checks here.  The strings are parsed into useful
6821  structures in the idmap daemon code.
6822
6823 ***************************************************************************/
6824
6825 /* Some lp_ routines to return idmap [ug]id information */
6826
6827 static uid_t idmap_uid_low, idmap_uid_high;
6828 static gid_t idmap_gid_low, idmap_gid_high;
6829
6830 bool lp_idmap_uid(uid_t *low, uid_t *high)
6831 {
6832         if (idmap_uid_low == 0 || idmap_uid_high == 0)
6833                 return False;
6834
6835         if (low)
6836                 *low = idmap_uid_low;
6837
6838         if (high)
6839                 *high = idmap_uid_high;
6840
6841         return True;
6842 }
6843
6844 bool lp_idmap_gid(gid_t *low, gid_t *high)
6845 {
6846         if (idmap_gid_low == 0 || idmap_gid_high == 0)
6847                 return False;
6848
6849         if (low)
6850                 *low = idmap_gid_low;
6851
6852         if (high)
6853                 *high = idmap_gid_high;
6854
6855         return True;
6856 }
6857
6858 /* Do some simple checks on "idmap [ug]id" parameter values */
6859
6860 static bool handle_idmap_uid(int snum, const char *pszParmValue, char **ptr)
6861 {
6862         uint32 low, high;
6863
6864         if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
6865                 return False;
6866
6867         /* Parse OK */
6868
6869         string_set(ptr, pszParmValue);
6870
6871         idmap_uid_low = low;
6872         idmap_uid_high = high;
6873
6874         return True;
6875 }
6876
6877 static bool handle_idmap_gid(int snum, const char *pszParmValue, char **ptr)
6878 {
6879         uint32 low, high;
6880
6881         if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
6882                 return False;
6883
6884         /* Parse OK */
6885
6886         string_set(ptr, pszParmValue);
6887
6888         idmap_gid_low = low;
6889         idmap_gid_high = high;
6890
6891         return True;
6892 }
6893
6894 /***************************************************************************
6895  Handle the DEBUG level list.
6896 ***************************************************************************/
6897
6898 static bool handle_debug_list( int snum, const char *pszParmValueIn, char **ptr )
6899 {
6900         string_set(ptr, pszParmValueIn);
6901         return debug_parse_levels(pszParmValueIn);
6902 }
6903
6904 /***************************************************************************
6905  Handle ldap suffixes - default to ldapsuffix if sub-suffixes are not defined.
6906 ***************************************************************************/
6907
6908 static const char *append_ldap_suffix( const char *str )
6909 {
6910         const char *suffix_string;
6911
6912
6913         suffix_string = talloc_asprintf(talloc_tos(), "%s,%s", str,
6914                                         Globals.szLdapSuffix );
6915         if ( !suffix_string ) {
6916                 DEBUG(0,("append_ldap_suffix: talloc_asprintf() failed!\n"));
6917                 return "";
6918         }
6919
6920         return suffix_string;
6921 }
6922
6923 const char *lp_ldap_machine_suffix(void)
6924 {
6925         if (Globals.szLdapMachineSuffix[0])
6926                 return append_ldap_suffix(Globals.szLdapMachineSuffix);
6927
6928         return lp_string(Globals.szLdapSuffix);
6929 }
6930
6931 const char *lp_ldap_user_suffix(void)
6932 {
6933         if (Globals.szLdapUserSuffix[0])
6934                 return append_ldap_suffix(Globals.szLdapUserSuffix);
6935
6936         return lp_string(Globals.szLdapSuffix);
6937 }
6938
6939 const char *lp_ldap_group_suffix(void)
6940 {
6941         if (Globals.szLdapGroupSuffix[0])
6942                 return append_ldap_suffix(Globals.szLdapGroupSuffix);
6943
6944         return lp_string(Globals.szLdapSuffix);
6945 }
6946
6947 const char *lp_ldap_idmap_suffix(void)
6948 {
6949         if (Globals.szLdapIdmapSuffix[0])
6950                 return append_ldap_suffix(Globals.szLdapIdmapSuffix);
6951
6952         return lp_string(Globals.szLdapSuffix);
6953 }
6954
6955 /****************************************************************************
6956  set the value for a P_ENUM
6957  ***************************************************************************/
6958
6959 static void lp_set_enum_parm( struct parm_struct *parm, const char *pszParmValue,
6960                               int *ptr )
6961 {
6962         int i;
6963
6964         for (i = 0; parm->enum_list[i].name; i++) {
6965                 if ( strequal(pszParmValue, parm->enum_list[i].name)) {
6966                         *ptr = parm->enum_list[i].value;
6967                         break;
6968                 }
6969         }
6970 }
6971
6972 /***************************************************************************
6973 ***************************************************************************/
6974
6975 static bool handle_printing(int snum, const char *pszParmValue, char **ptr)
6976 {
6977         static int parm_num = -1;
6978         struct service *s;
6979
6980         if ( parm_num == -1 )
6981                 parm_num = map_parameter( "printing" );
6982
6983         lp_set_enum_parm( &parm_table[parm_num], pszParmValue, (int*)ptr );
6984
6985         if ( snum < 0 )
6986                 s = &sDefault;
6987         else
6988                 s = ServicePtrs[snum];
6989
6990         init_printer_values( s );
6991
6992         return True;
6993 }
6994
6995
6996 /***************************************************************************
6997  Initialise a copymap.
6998 ***************************************************************************/
6999
7000 static void init_copymap(struct service *pservice)
7001 {
7002         int i;
7003         if (pservice->copymap) {
7004                 bitmap_free(pservice->copymap);
7005         }
7006         pservice->copymap = bitmap_allocate(NUMPARAMETERS);
7007         if (!pservice->copymap)
7008                 DEBUG(0,
7009                       ("Couldn't allocate copymap!! (size %d)\n",
7010                        (int)NUMPARAMETERS));
7011         else
7012                 for (i = 0; i < NUMPARAMETERS; i++)
7013                         bitmap_set(pservice->copymap, i);
7014 }
7015
7016 /***************************************************************************
7017  Return the local pointer to a parameter given the service number and the 
7018  pointer into the default structure.
7019 ***************************************************************************/
7020
7021 void *lp_local_ptr(int snum, void *ptr)
7022 {
7023         return (void *)(((char *)ServicePtrs[snum]) + PTR_DIFF(ptr, &sDefault));
7024 }
7025
7026 /***************************************************************************
7027  Process a parameter for a particular service number. If snum < 0
7028  then assume we are in the globals.
7029 ***************************************************************************/
7030
7031 bool lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
7032 {
7033         int parmnum, i, slen;
7034         void *parm_ptr = NULL;  /* where we are going to store the result */
7035         void *def_ptr = NULL;
7036         char *param_key = NULL;
7037         char *sep;
7038         param_opt_struct *paramo, *data;
7039         bool not_added;
7040
7041         parmnum = map_parameter(pszParmName);
7042
7043         if (parmnum < 0) {
7044                 if ((sep=strchr(pszParmName, ':')) != NULL) {
7045                         TALLOC_CTX *frame = talloc_stackframe();
7046
7047                         *sep = '\0';
7048                         param_key = talloc_asprintf(frame, "%s:", pszParmName);
7049                         if (!param_key) {
7050                                 TALLOC_FREE(frame);
7051                                 return false;
7052                         }
7053                         slen = strlen(param_key);
7054                         param_key = talloc_asprintf_append(param_key, sep+1);
7055                         if (!param_key) {
7056                                 TALLOC_FREE(frame);
7057                                 return false;
7058                         }
7059                         trim_char(param_key+slen, ' ', ' ');
7060                         not_added = True;
7061                         data = (snum < 0) ? Globals.param_opt :
7062                                 ServicePtrs[snum]->param_opt;
7063                         /* Traverse destination */
7064                         while (data) {
7065                                 /* If we already have same option, override it */
7066                                 if (strcmp(data->key, param_key) == 0) {
7067                                         string_free(&data->value);
7068                                         TALLOC_FREE(data->list);
7069                                         data->value = SMB_STRDUP(pszParmValue);
7070                                         not_added = False;
7071                                         break;
7072                                 }
7073                                 data = data->next;
7074                         }
7075                         if (not_added) {
7076                                 paramo = SMB_XMALLOC_P(param_opt_struct);
7077                                 paramo->key = SMB_STRDUP(param_key);
7078                                 paramo->value = SMB_STRDUP(pszParmValue);
7079                                 paramo->list = NULL;
7080                                 if (snum < 0) {
7081                                         DLIST_ADD(Globals.param_opt, paramo);
7082                                 } else {
7083                                         DLIST_ADD(ServicePtrs[snum]->param_opt, paramo);
7084                                 }
7085                         }
7086
7087                         *sep = ':';
7088                         TALLOC_FREE(frame);
7089                         return (True);
7090                 }
7091                 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
7092                 return (True);
7093         }
7094
7095         if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
7096                 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
7097                           pszParmName));
7098         }
7099
7100         def_ptr = parm_table[parmnum].ptr;
7101
7102         /* we might point at a service, the default service or a global */
7103         if (snum < 0) {
7104                 parm_ptr = def_ptr;
7105         } else {
7106                 if (parm_table[parmnum].p_class == P_GLOBAL) {
7107                         DEBUG(0,
7108                               ("Global parameter %s found in service section!\n",
7109                                pszParmName));
7110                         return (True);
7111                 }
7112                 parm_ptr =
7113                         ((char *)ServicePtrs[snum]) + PTR_DIFF(def_ptr,
7114                                                             &sDefault);
7115         }
7116
7117         if (snum >= 0) {
7118                 if (!ServicePtrs[snum]->copymap)
7119                         init_copymap(ServicePtrs[snum]);
7120
7121                 /* this handles the aliases - set the copymap for other entries with
7122                    the same data pointer */
7123                 for (i = 0; parm_table[i].label; i++)
7124                         if (parm_table[i].ptr == parm_table[parmnum].ptr)
7125                                 bitmap_clear(ServicePtrs[snum]->copymap, i);
7126         }
7127
7128         /* if it is a special case then go ahead */
7129         if (parm_table[parmnum].special) {
7130                 parm_table[parmnum].special(snum, pszParmValue, (char **)parm_ptr);
7131                 return (True);
7132         }
7133
7134         /* now switch on the type of variable it is */
7135         switch (parm_table[parmnum].type)
7136         {
7137                 case P_BOOL:
7138                         *(bool *)parm_ptr = lp_bool(pszParmValue);
7139                         break;
7140
7141                 case P_BOOLREV:
7142                         *(bool *)parm_ptr = !lp_bool(pszParmValue);
7143                         break;
7144
7145                 case P_INTEGER:
7146                         *(int *)parm_ptr = lp_int(pszParmValue);
7147                         break;
7148
7149                 case P_CHAR:
7150                         *(char *)parm_ptr = *pszParmValue;
7151                         break;
7152
7153                 case P_OCTAL:
7154                         i = sscanf(pszParmValue, "%o", (int *)parm_ptr);
7155                         if ( i != 1 ) {
7156                             DEBUG ( 0, ("Invalid octal number %s\n", pszParmName ));
7157                         }
7158                         break;
7159
7160                 case P_LIST:
7161                         TALLOC_FREE(*((char ***)parm_ptr));
7162                         *(char ***)parm_ptr = str_list_make(
7163                                 NULL, pszParmValue, NULL);
7164                         break;
7165
7166                 case P_STRING:
7167                         string_set((char **)parm_ptr, pszParmValue);
7168                         break;
7169
7170                 case P_USTRING:
7171                         string_set((char **)parm_ptr, pszParmValue);
7172                         strupper_m(*(char **)parm_ptr);
7173                         break;
7174
7175                 case P_ENUM:
7176                         lp_set_enum_parm( &parm_table[parmnum], pszParmValue, (int*)parm_ptr );
7177                         break;
7178                 case P_SEP:
7179                         break;
7180         }
7181
7182         return (True);
7183 }
7184
7185 /***************************************************************************
7186  Process a parameter.
7187 ***************************************************************************/
7188
7189 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
7190                          void *userdata)
7191 {
7192         if (!bInGlobalSection && bGlobalOnly)
7193                 return (True);
7194
7195         DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
7196
7197         return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
7198                                 pszParmName, pszParmValue));
7199 }
7200
7201 /***************************************************************************
7202  Print a parameter of the specified type.
7203 ***************************************************************************/
7204
7205 static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
7206 {
7207         int i;
7208         switch (p->type)
7209         {
7210                 case P_ENUM:
7211                         for (i = 0; p->enum_list[i].name; i++) {
7212                                 if (*(int *)ptr == p->enum_list[i].value) {
7213                                         fprintf(f, "%s",
7214                                                 p->enum_list[i].name);
7215                                         break;
7216                                 }
7217                         }
7218                         break;
7219
7220                 case P_BOOL:
7221                         fprintf(f, "%s", BOOLSTR(*(bool *)ptr));
7222                         break;
7223
7224                 case P_BOOLREV:
7225                         fprintf(f, "%s", BOOLSTR(!*(bool *)ptr));
7226                         break;
7227
7228                 case P_INTEGER:
7229                         fprintf(f, "%d", *(int *)ptr);
7230                         break;
7231
7232                 case P_CHAR:
7233                         fprintf(f, "%c", *(char *)ptr);
7234                         break;
7235
7236                 case P_OCTAL: {
7237                         char *o = octal_string(*(int *)ptr);
7238                         fprintf(f, "%s", o);
7239                         TALLOC_FREE(o);
7240                         break;
7241                 }
7242
7243                 case P_LIST:
7244                         if ((char ***)ptr && *(char ***)ptr) {
7245                                 char **list = *(char ***)ptr;
7246                                 for (; *list; list++) {
7247                                         /* surround strings with whitespace in double quotes */
7248                                         if ( strchr_m( *list, ' ' ) )
7249                                                 fprintf(f, "\"%s\"%s", *list, ((*(list+1))?", ":""));
7250                                         else
7251                                                 fprintf(f, "%s%s", *list, ((*(list+1))?", ":""));
7252                                 }
7253                         }
7254                         break;
7255
7256                 case P_STRING:
7257                 case P_USTRING:
7258                         if (*(char **)ptr) {
7259                                 fprintf(f, "%s", *(char **)ptr);
7260                         }
7261                         break;
7262                 case P_SEP:
7263                         break;
7264         }
7265 }
7266
7267 /***************************************************************************
7268  Check if two parameters are equal.
7269 ***************************************************************************/
7270
7271 static bool equal_parameter(parm_type type, void *ptr1, void *ptr2)
7272 {
7273         switch (type) {
7274                 case P_BOOL:
7275                 case P_BOOLREV:
7276                         return (*((bool *)ptr1) == *((bool *)ptr2));
7277
7278                 case P_INTEGER:
7279                 case P_ENUM:
7280                 case P_OCTAL:
7281                         return (*((int *)ptr1) == *((int *)ptr2));
7282
7283                 case P_CHAR:
7284                         return (*((char *)ptr1) == *((char *)ptr2));
7285
7286                 case P_LIST:
7287                         return str_list_compare(*(char ***)ptr1, *(char ***)ptr2);
7288
7289                 case P_STRING:
7290                 case P_USTRING:
7291                 {
7292                         char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
7293                         if (p1 && !*p1)
7294                                 p1 = NULL;
7295                         if (p2 && !*p2)
7296                                 p2 = NULL;
7297                         return (p1 == p2 || strequal(p1, p2));
7298                 }
7299                 case P_SEP:
7300                         break;
7301         }
7302         return (False);
7303 }
7304
7305 /***************************************************************************
7306  Initialize any local varients in the sDefault table.
7307 ***************************************************************************/
7308
7309 void init_locals(void)
7310 {
7311         /* None as yet. */
7312 }
7313
7314 /***************************************************************************
7315  Process a new section (service). At this stage all sections are services.
7316  Later we'll have special sections that permit server parameters to be set.
7317  Returns True on success, False on failure. 
7318 ***************************************************************************/
7319
7320 static bool do_section(const char *pszSectionName, void *userdata)
7321 {
7322         bool bRetval;
7323         bool isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
7324                          (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
7325         bRetval = False;
7326
7327         /* if we were in a global section then do the local inits */
7328         if (bInGlobalSection && !isglobal)
7329                 init_locals();
7330
7331         /* if we've just struck a global section, note the fact. */
7332         bInGlobalSection = isglobal;
7333
7334         /* check for multiple global sections */
7335         if (bInGlobalSection) {
7336                 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
7337                 return (True);
7338         }
7339
7340         if (!bInGlobalSection && bGlobalOnly)
7341                 return (True);
7342
7343         /* if we have a current service, tidy it up before moving on */
7344         bRetval = True;
7345
7346         if (iServiceIndex >= 0)
7347                 bRetval = service_ok(iServiceIndex);
7348
7349         /* if all is still well, move to the next record in the services array */
7350         if (bRetval) {
7351                 /* We put this here to avoid an odd message order if messages are */
7352                 /* issued by the post-processing of a previous section. */
7353                 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
7354
7355                 if ((iServiceIndex = add_a_service(&sDefault, pszSectionName))
7356                     < 0) {
7357                         DEBUG(0, ("Failed to add a new service\n"));
7358                         return (False);
7359                 }
7360         }
7361
7362         return (bRetval);
7363 }
7364
7365
7366 /***************************************************************************
7367  Determine if a partcular base parameter is currentl set to the default value.
7368 ***************************************************************************/
7369
7370 static bool is_default(int i)
7371 {
7372         if (!defaults_saved)
7373                 return False;
7374         switch (parm_table[i].type) {
7375                 case P_LIST:
7376                         return str_list_compare (parm_table[i].def.lvalue, 
7377                                                 *(char ***)parm_table[i].ptr);
7378                 case P_STRING:
7379                 case P_USTRING:
7380                         return strequal(parm_table[i].def.svalue,
7381                                         *(char **)parm_table[i].ptr);
7382                 case P_BOOL:
7383                 case P_BOOLREV:
7384                         return parm_table[i].def.bvalue ==
7385                                 *(bool *)parm_table[i].ptr;
7386                 case P_CHAR:
7387                         return parm_table[i].def.cvalue ==
7388                                 *(char *)parm_table[i].ptr;
7389                 case P_INTEGER:
7390                 case P_OCTAL:
7391                 case P_ENUM:
7392                         return parm_table[i].def.ivalue ==
7393                                 *(int *)parm_table[i].ptr;
7394                 case P_SEP:
7395                         break;
7396         }
7397         return False;
7398 }
7399
7400 /***************************************************************************
7401 Display the contents of the global structure.
7402 ***************************************************************************/
7403
7404 static void dump_globals(FILE *f)
7405 {
7406         int i;
7407         param_opt_struct *data;
7408         
7409         fprintf(f, "[global]\n");
7410
7411         for (i = 0; parm_table[i].label; i++)
7412                 if (parm_table[i].p_class == P_GLOBAL &&
7413                     parm_table[i].ptr &&
7414                     (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
7415                         if (defaults_saved && is_default(i))
7416                                 continue;
7417                         fprintf(f, "\t%s = ", parm_table[i].label);
7418                         print_parameter(&parm_table[i], parm_table[i].ptr, f);
7419                         fprintf(f, "\n");
7420         }
7421         if (Globals.param_opt != NULL) {
7422                 data = Globals.param_opt;
7423                 while(data) {
7424                         fprintf(f, "\t%s = %s\n", data->key, data->value);
7425                         data = data->next;
7426                 }
7427         }
7428
7429 }
7430
7431 /***************************************************************************
7432  Return True if a local parameter is currently set to the global default.
7433 ***************************************************************************/
7434
7435 bool lp_is_default(int snum, struct parm_struct *parm)
7436 {
7437         int pdiff = PTR_DIFF(parm->ptr, &sDefault);
7438
7439         return equal_parameter(parm->type,
7440                                ((char *)ServicePtrs[snum]) + pdiff,
7441                                ((char *)&sDefault) + pdiff);
7442 }
7443
7444 /***************************************************************************
7445  Display the contents of a single services record.
7446 ***************************************************************************/
7447
7448 static void dump_a_service(struct service *pService, FILE * f)
7449 {
7450         int i;
7451         param_opt_struct *data;
7452         
7453         if (pService != &sDefault)
7454                 fprintf(f, "[%s]\n", pService->szService);
7455
7456         for (i = 0; parm_table[i].label; i++) {
7457
7458                 if (parm_table[i].p_class == P_LOCAL &&
7459                     parm_table[i].ptr &&
7460                     (*parm_table[i].label != '-') &&
7461                     (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) 
7462                 {
7463                 
7464                         int pdiff = PTR_DIFF(parm_table[i].ptr, &sDefault);
7465
7466                         if (pService == &sDefault) {
7467                                 if (defaults_saved && is_default(i))
7468                                         continue;
7469                         } else {
7470                                 if (equal_parameter(parm_table[i].type,
7471                                                     ((char *)pService) +
7472                                                     pdiff,
7473                                                     ((char *)&sDefault) +
7474                                                     pdiff))
7475                                         continue;
7476                         }
7477
7478                         fprintf(f, "\t%s = ", parm_table[i].label);
7479                         print_parameter(&parm_table[i],
7480                                         ((char *)pService) + pdiff, f);
7481                         fprintf(f, "\n");
7482                 }
7483         }
7484
7485                 if (pService->param_opt != NULL) {
7486                         data = pService->param_opt;
7487                         while(data) {
7488                                 fprintf(f, "\t%s = %s\n", data->key, data->value);
7489                                 data = data->next;
7490                         }
7491                 }
7492 }
7493
7494 /***************************************************************************
7495  Display the contents of a parameter of a single services record.
7496 ***************************************************************************/
7497
7498 bool dump_a_parameter(int snum, char *parm_name, FILE * f, bool isGlobal)
7499 {
7500         int i;
7501         bool result = False;
7502         parm_class p_class;
7503         unsigned flag = 0;
7504         fstring local_parm_name;
7505         char *parm_opt;
7506         const char *parm_opt_value;
7507
7508         /* check for parametrical option */
7509         fstrcpy( local_parm_name, parm_name);
7510         parm_opt = strchr( local_parm_name, ':');
7511
7512         if (parm_opt) {
7513                 *parm_opt = '\0';
7514                 parm_opt++;
7515                 if (strlen(parm_opt)) {
7516                         parm_opt_value = lp_parm_const_string( snum,
7517                                 local_parm_name, parm_opt, NULL);
7518                         if (parm_opt_value) {
7519                                 printf( "%s\n", parm_opt_value);
7520                                 result = True;
7521                         }
7522                 }
7523                 return result;
7524         }
7525
7526         /* check for a key and print the value */
7527         if (isGlobal) {
7528                 p_class = P_GLOBAL;
7529                 flag = FLAG_GLOBAL;
7530         } else
7531                 p_class = P_LOCAL;
7532
7533         for (i = 0; parm_table[i].label; i++) {
7534                 if (strwicmp(parm_table[i].label, parm_name) == 0 &&
7535                     (parm_table[i].p_class == p_class || parm_table[i].flags & flag) &&
7536                     parm_table[i].ptr &&
7537                     (*parm_table[i].label != '-') &&
7538                     (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) 
7539                 {
7540                         void *ptr;
7541
7542                         if (isGlobal) {
7543                                 ptr = parm_table[i].ptr;
7544                         } else {
7545                                 struct service *pService = ServicePtrs[snum];
7546                                 ptr = ((char *)pService) +
7547                                         PTR_DIFF(parm_table[i].ptr, &sDefault);
7548                         }
7549
7550                         print_parameter(&parm_table[i],
7551                                         ptr, f);
7552                         fprintf(f, "\n");
7553                         result = True;
7554                         break;
7555                 }
7556         }
7557
7558         return result;
7559 }
7560
7561 /***************************************************************************
7562  Return info about the requested parameter (given as a string).
7563  Return NULL when the string is not a valid parameter name.
7564 ***************************************************************************/
7565
7566 struct parm_struct *lp_get_parameter(const char *param_name)
7567 {
7568         int num = map_parameter(param_name);
7569
7570         if (num < 0) {
7571                 return NULL;
7572         }
7573
7574         return &parm_table[num];
7575 }
7576
7577 /***************************************************************************
7578  Return info about the next parameter in a service.
7579  snum==GLOBAL_SECTION_SNUM gives the globals.
7580  Return NULL when out of parameters.
7581 ***************************************************************************/
7582
7583 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
7584 {
7585         if (snum < 0) {
7586                 /* do the globals */
7587                 for (; parm_table[*i].label; (*i)++) {
7588                         if (parm_table[*i].p_class == P_SEPARATOR)
7589                                 return &parm_table[(*i)++];
7590
7591                         if (!parm_table[*i].ptr
7592                             || (*parm_table[*i].label == '-'))
7593                                 continue;
7594
7595                         if ((*i) > 0
7596                             && (parm_table[*i].ptr ==
7597                                 parm_table[(*i) - 1].ptr))
7598                                 continue;
7599                         
7600                         if (is_default(*i) && !allparameters)
7601                                 continue;
7602
7603                         return &parm_table[(*i)++];
7604                 }
7605         } else {
7606                 struct service *pService = ServicePtrs[snum];
7607
7608                 for (; parm_table[*i].label; (*i)++) {
7609                         if (parm_table[*i].p_class == P_SEPARATOR)
7610                                 return &parm_table[(*i)++];
7611
7612                         if (parm_table[*i].p_class == P_LOCAL &&
7613                             parm_table[*i].ptr &&
7614                             (*parm_table[*i].label != '-') &&
7615                             ((*i) == 0 ||
7616                              (parm_table[*i].ptr !=
7617                               parm_table[(*i) - 1].ptr)))
7618                         {
7619                                 int pdiff =
7620                                         PTR_DIFF(parm_table[*i].ptr,
7621                                                  &sDefault);
7622
7623                                 if (allparameters ||
7624                                     !equal_parameter(parm_table[*i].type,
7625                                                      ((char *)pService) +
7626                                                      pdiff,
7627                                                      ((char *)&sDefault) +
7628                                                      pdiff))
7629                                 {
7630                                         return &parm_table[(*i)++];
7631                                 }
7632                         }
7633                 }
7634         }
7635
7636         return NULL;
7637 }
7638
7639
7640 #if 0
7641 /***************************************************************************
7642  Display the contents of a single copy structure.
7643 ***************************************************************************/
7644 static void dump_copy_map(bool *pcopymap)
7645 {
7646         int i;
7647         if (!pcopymap)
7648                 return;
7649
7650         printf("\n\tNon-Copied parameters:\n");
7651
7652         for (i = 0; parm_table[i].label; i++)
7653                 if (parm_table[i].p_class == P_LOCAL &&
7654                     parm_table[i].ptr && !pcopymap[i] &&
7655                     (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
7656                 {
7657                         printf("\t\t%s\n", parm_table[i].label);
7658                 }
7659 }
7660 #endif
7661
7662 /***************************************************************************
7663  Return TRUE if the passed service number is within range.
7664 ***************************************************************************/
7665
7666 bool lp_snum_ok(int iService)
7667 {
7668         return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
7669 }
7670
7671 /***************************************************************************
7672  Auto-load some home services.
7673 ***************************************************************************/
7674
7675 static void lp_add_auto_services(char *str)
7676 {
7677         char *s;
7678         char *p;
7679         int homes;
7680         char *saveptr;
7681
7682         if (!str)
7683                 return;
7684
7685         s = SMB_STRDUP(str);
7686         if (!s)
7687                 return;
7688
7689         homes = lp_servicenumber(HOMES_NAME);
7690
7691         for (p = strtok_r(s, LIST_SEP, &saveptr); p;
7692              p = strtok_r(NULL, LIST_SEP, &saveptr)) {
7693                 char *home;
7694
7695                 if (lp_servicenumber(p) >= 0)
7696                         continue;
7697
7698                 home = get_user_home_dir(talloc_tos(), p);
7699
7700                 if (home && homes >= 0)
7701                         lp_add_home(p, homes, p, home);
7702
7703                 TALLOC_FREE(home);
7704         }
7705         SAFE_FREE(s);
7706 }
7707
7708 /***************************************************************************
7709  Auto-load one printer.
7710 ***************************************************************************/
7711
7712 void lp_add_one_printer(char *name, char *comment)
7713 {
7714         int printers = lp_servicenumber(PRINTERS_NAME);
7715         int i;
7716
7717         if (lp_servicenumber(name) < 0) {
7718                 lp_add_printer(name, printers);
7719                 if ((i = lp_servicenumber(name)) >= 0) {
7720                         string_set(&ServicePtrs[i]->comment, comment);
7721                         ServicePtrs[i]->autoloaded = True;
7722                 }
7723         }
7724 }
7725
7726 /***************************************************************************
7727  Have we loaded a services file yet?
7728 ***************************************************************************/
7729
7730 bool lp_loaded(void)
7731 {
7732         return (bLoaded);
7733 }
7734
7735 /***************************************************************************
7736  Unload unused services.
7737 ***************************************************************************/
7738
7739 void lp_killunused(bool (*snumused) (int))
7740 {
7741         int i;
7742         for (i = 0; i < iNumServices; i++) {
7743                 if (!VALID(i))
7744                         continue;
7745
7746                 /* don't kill autoloaded or usershare services */
7747                 if ( ServicePtrs[i]->autoloaded ||
7748                                 ServicePtrs[i]->usershare == USERSHARE_VALID) {
7749                         continue;
7750                 }
7751
7752                 if (!snumused || !snumused(i)) {
7753                         free_service_byindex(i);
7754                 }
7755         }
7756 }
7757
7758 /**
7759  * Kill all except autoloaded and usershare services - convenience wrapper
7760  */
7761 void lp_kill_all_services(void)
7762 {
7763         lp_killunused(NULL);
7764 }
7765
7766 /***************************************************************************
7767  Unload a service.
7768 ***************************************************************************/
7769
7770 void lp_killservice(int iServiceIn)
7771 {
7772         if (VALID(iServiceIn)) {
7773                 free_service_byindex(iServiceIn);
7774         }
7775 }
7776
7777 /***************************************************************************
7778  Save the curent values of all global and sDefault parameters into the 
7779  defaults union. This allows swat and testparm to show only the
7780  changed (ie. non-default) parameters.
7781 ***************************************************************************/
7782
7783 static void lp_save_defaults(void)
7784 {
7785         int i;
7786         for (i = 0; parm_table[i].label; i++) {
7787                 if (i > 0 && parm_table[i].ptr == parm_table[i - 1].ptr)
7788                         continue;
7789                 switch (parm_table[i].type) {
7790                         case P_LIST:
7791                                 str_list_copy(
7792                                         NULL, &(parm_table[i].def.lvalue),
7793                                         *(const char ***)parm_table[i].ptr);
7794                                 break;
7795                         case P_STRING:
7796                         case P_USTRING:
7797                                 if (parm_table[i].ptr) {
7798                                         parm_table[i].def.svalue = SMB_STRDUP(*(char **)parm_table[i].ptr);
7799                                 } else {
7800                                         parm_table[i].def.svalue = NULL;
7801                                 }
7802                                 break;
7803                         case P_BOOL:
7804                         case P_BOOLREV:
7805                                 parm_table[i].def.bvalue =
7806                                         *(bool *)parm_table[i].ptr;
7807                                 break;
7808                         case P_CHAR:
7809                                 parm_table[i].def.cvalue =
7810                                         *(char *)parm_table[i].ptr;
7811                                 break;
7812                         case P_INTEGER:
7813                         case P_OCTAL:
7814                         case P_ENUM:
7815                                 parm_table[i].def.ivalue =
7816                                         *(int *)parm_table[i].ptr;
7817                                 break;
7818                         case P_SEP:
7819                                 break;
7820                 }
7821         }
7822         defaults_saved = True;
7823 }
7824
7825 /*******************************************************************
7826  Set the server type we will announce as via nmbd.
7827 ********************************************************************/
7828
7829 static const struct srv_role_tab {
7830         uint32 role;
7831         const char *role_str;
7832 } srv_role_tab [] = {
7833         { ROLE_STANDALONE, "ROLE_STANDALONE" },
7834         { ROLE_DOMAIN_MEMBER, "ROLE_DOMAIN_MEMBER" },
7835         { ROLE_DOMAIN_BDC, "ROLE_DOMAIN_BDC" },
7836         { ROLE_DOMAIN_PDC, "ROLE_DOMAIN_PDC" },
7837         { 0, NULL }
7838 };
7839
7840 const char* server_role_str(uint32 role)
7841 {
7842         int i = 0;
7843         for (i=0; srv_role_tab[i].role_str; i++) {
7844                 if (role == srv_role_tab[i].role) {
7845                         return srv_role_tab[i].role_str;
7846                 }
7847         }
7848         return NULL;
7849 }
7850
7851 static void set_server_role(void)
7852 {
7853         server_role = ROLE_STANDALONE;
7854
7855         switch (lp_security()) {
7856                 case SEC_SHARE:
7857                         if (lp_domain_logons())
7858                                 DEBUG(0, ("Server's Role (logon server) conflicts with share-level security\n"));
7859                         break;
7860                 case SEC_SERVER:
7861                         if (lp_domain_logons())
7862                                 DEBUG(0, ("Server's Role (logon server) conflicts with server-level security\n"));
7863                         /* this used to be considered ROLE_DOMAIN_MEMBER but that's just wrong */
7864                         server_role = ROLE_STANDALONE;
7865                         break;
7866                 case SEC_DOMAIN:
7867                         if (lp_domain_logons()) {
7868                                 DEBUG(1, ("Server's Role (logon server) NOT ADVISED with domain-level security\n"));
7869                                 server_role = ROLE_DOMAIN_BDC;
7870                                 break;
7871                         }
7872                         server_role = ROLE_DOMAIN_MEMBER;
7873                         break;
7874                 case SEC_ADS:
7875                         if (lp_domain_logons()) {
7876                                 server_role = ROLE_DOMAIN_PDC;
7877                                 break;
7878                         }
7879                         server_role = ROLE_DOMAIN_MEMBER;
7880                         break;
7881                 case SEC_USER:
7882                         if (lp_domain_logons()) {
7883
7884                                 if (Globals.iDomainMaster) /* auto or yes */ 
7885                                         server_role = ROLE_DOMAIN_PDC;
7886                                 else
7887                                         server_role = ROLE_DOMAIN_BDC;
7888                         }
7889                         break;
7890                 default:
7891                         DEBUG(0, ("Server's Role undefined due to unknown security mode\n"));
7892                         break;
7893         }
7894
7895         DEBUG(10, ("set_server_role: role = %s\n", server_role_str(server_role)));
7896 }
7897
7898 /***********************************************************
7899  If we should send plaintext/LANMAN passwords in the clinet
7900 ************************************************************/
7901
7902 static void set_allowed_client_auth(void)
7903 {
7904         if (Globals.bClientNTLMv2Auth) {
7905                 Globals.bClientLanManAuth = False;
7906         }
7907         if (!Globals.bClientLanManAuth) {
7908                 Globals.bClientPlaintextAuth = False;
7909         }
7910 }
7911
7912 /***************************************************************************
7913  JRA.
7914  The following code allows smbd to read a user defined share file.
7915  Yes, this is my intent. Yes, I'm comfortable with that...
7916
7917  THE FOLLOWING IS SECURITY CRITICAL CODE.
7918
7919  It washes your clothes, it cleans your house, it guards you while you sleep...
7920  Do not f%^k with it....
7921 ***************************************************************************/
7922
7923 #define MAX_USERSHARE_FILE_SIZE (10*1024)
7924
7925 /***************************************************************************
7926  Check allowed stat state of a usershare file.
7927  Ensure we print out who is dicking with us so the admin can
7928  get their sorry ass fired.
7929 ***************************************************************************/
7930
7931 static bool check_usershare_stat(const char *fname, SMB_STRUCT_STAT *psbuf)
7932 {
7933         if (!S_ISREG(psbuf->st_mode)) {
7934                 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
7935                         "not a regular file\n",
7936                         fname, (unsigned int)psbuf->st_uid ));
7937                 return False;
7938         }
7939
7940         /* Ensure this doesn't have the other write bit set. */
7941         if (psbuf->st_mode & S_IWOTH) {
7942                 DEBUG(0,("check_usershare_stat: file %s owned by uid %u allows "
7943                         "public write. Refusing to allow as a usershare file.\n",
7944                         fname, (unsigned int)psbuf->st_uid ));
7945                 return False;
7946         }
7947
7948         /* Should be 10k or less. */
7949         if (psbuf->st_size > MAX_USERSHARE_FILE_SIZE) {
7950                 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
7951                         "too large (%u) to be a user share file.\n",
7952                         fname, (unsigned int)psbuf->st_uid,
7953                         (unsigned int)psbuf->st_size ));
7954                 return False;
7955         }
7956
7957         return True;
7958 }
7959
7960 /***************************************************************************
7961  Parse the contents of a usershare file.
7962 ***************************************************************************/
7963
7964 enum usershare_err parse_usershare_file(TALLOC_CTX *ctx,
7965                         SMB_STRUCT_STAT *psbuf,
7966                         const char *servicename,
7967                         int snum,
7968                         char **lines,
7969                         int numlines,
7970                         char **pp_sharepath,
7971                         char **pp_comment,
7972                         SEC_DESC **ppsd,
7973                         bool *pallow_guest)
7974 {
7975         const char **prefixallowlist = lp_usershare_prefix_allow_list();
7976         const char **prefixdenylist = lp_usershare_prefix_deny_list();
7977         int us_vers;
7978         SMB_STRUCT_DIR *dp;
7979         SMB_STRUCT_STAT sbuf;
7980         char *sharepath = NULL;
7981         char *comment = NULL;
7982
7983         *pp_sharepath = NULL;
7984         *pp_comment = NULL;
7985
7986         *pallow_guest = False;
7987
7988         if (numlines < 4) {
7989                 return USERSHARE_MALFORMED_FILE;
7990         }
7991
7992         if (strcmp(lines[0], "#VERSION 1") == 0) {
7993                 us_vers = 1;
7994         } else if (strcmp(lines[0], "#VERSION 2") == 0) {
7995                 us_vers = 2;
7996                 if (numlines < 5) {
7997                         return USERSHARE_MALFORMED_FILE;
7998                 }
7999         } else {
8000                 return USERSHARE_BAD_VERSION;
8001         }
8002
8003         if (strncmp(lines[1], "path=", 5) != 0) {
8004                 return USERSHARE_MALFORMED_PATH;
8005         }
8006
8007         sharepath = talloc_strdup(ctx, &lines[1][5]);
8008         if (!sharepath) {
8009                 return USERSHARE_POSIX_ERR;
8010         }
8011         trim_string(sharepath, " ", " ");
8012
8013         if (strncmp(lines[2], "comment=", 8) != 0) {
8014                 return USERSHARE_MALFORMED_COMMENT_DEF;
8015         }
8016
8017         comment = talloc_strdup(ctx, &lines[2][8]);
8018         if (!comment) {
8019                 return USERSHARE_POSIX_ERR;
8020         }
8021         trim_string(comment, " ", " ");
8022         trim_char(comment, '"', '"');
8023
8024         if (strncmp(lines[3], "usershare_acl=", 14) != 0) {
8025                 return USERSHARE_MALFORMED_ACL_DEF;
8026         }
8027
8028         if (!parse_usershare_acl(ctx, &lines[3][14], ppsd)) {
8029                 return USERSHARE_ACL_ERR;
8030         }
8031
8032         if (us_vers == 2) {
8033                 if (strncmp(lines[4], "guest_ok=", 9) != 0) {
8034                         return USERSHARE_MALFORMED_ACL_DEF;
8035                 }
8036                 if (lines[4][9] == 'y') {
8037                         *pallow_guest = True;
8038                 }
8039         }
8040
8041         if (snum != -1 && (strcmp(sharepath, ServicePtrs[snum]->szPath) == 0)) {
8042                 /* Path didn't change, no checks needed. */
8043                 *pp_sharepath = sharepath;
8044                 *pp_comment = comment;
8045                 return USERSHARE_OK;
8046         }
8047
8048         /* The path *must* be absolute. */
8049         if (sharepath[0] != '/') {
8050                 DEBUG(2,("parse_usershare_file: share %s: path %s is not an absolute path.\n",
8051                         servicename, sharepath));
8052                 return USERSHARE_PATH_NOT_ABSOLUTE;
8053         }
8054
8055         /* If there is a usershare prefix deny list ensure one of these paths
8056            doesn't match the start of the user given path. */
8057         if (prefixdenylist) {
8058                 int i;
8059                 for ( i=0; prefixdenylist[i]; i++ ) {
8060                         DEBUG(10,("parse_usershare_file: share %s : checking prefixdenylist[%d]='%s' against %s\n",
8061                                 servicename, i, prefixdenylist[i], sharepath ));
8062                         if (memcmp( sharepath, prefixdenylist[i], strlen(prefixdenylist[i])) == 0) {
8063                                 DEBUG(2,("parse_usershare_file: share %s path %s starts with one of the "
8064                                         "usershare prefix deny list entries.\n",
8065                                         servicename, sharepath));
8066                                 return USERSHARE_PATH_IS_DENIED;
8067                         }
8068                 }
8069         }
8070
8071         /* If there is a usershare prefix allow list ensure one of these paths
8072            does match the start of the user given path. */
8073
8074         if (prefixallowlist) {
8075                 int i;
8076                 for ( i=0; prefixallowlist[i]; i++ ) {
8077                         DEBUG(10,("parse_usershare_file: share %s checking prefixallowlist[%d]='%s' against %s\n",
8078                                 servicename, i, prefixallowlist[i], sharepath ));
8079                         if (memcmp( sharepath, prefixallowlist[i], strlen(prefixallowlist[i])) == 0) {
8080                                 break;
8081                         }
8082                 }
8083                 if (prefixallowlist[i] == NULL) {
8084                         DEBUG(2,("parse_usershare_file: share %s path %s doesn't start with one of the "
8085                                 "usershare prefix allow list entries.\n",
8086                                 servicename, sharepath));
8087                         return USERSHARE_PATH_NOT_ALLOWED;
8088                 }
8089         }
8090
8091         /* Ensure this is pointing to a directory. */
8092         dp = sys_opendir(sharepath);
8093
8094         if (!dp) {
8095                 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
8096                         servicename, sharepath));
8097                 return USERSHARE_PATH_NOT_DIRECTORY;
8098         }
8099
8100         /* Ensure the owner of the usershare file has permission to share
8101            this directory. */
8102
8103         if (sys_stat(sharepath, &sbuf) == -1) {
8104                 DEBUG(2,("parse_usershare_file: share %s : stat failed on path %s. %s\n",
8105                         servicename, sharepath, strerror(errno) ));
8106                 sys_closedir(dp);
8107                 return USERSHARE_POSIX_ERR;
8108         }
8109
8110         sys_closedir(dp);
8111
8112         if (!S_ISDIR(sbuf.st_mode)) {
8113                 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
8114                         servicename, sharepath ));
8115                 return USERSHARE_PATH_NOT_DIRECTORY;
8116         }
8117
8118         /* Check if sharing is restricted to owner-only. */
8119         /* psbuf is the stat of the usershare definition file,
8120            sbuf is the stat of the target directory to be shared. */
8121
8122         if (lp_usershare_owner_only()) {
8123                 /* root can share anything. */
8124                 if ((psbuf->st_uid != 0) && (sbuf.st_uid != psbuf->st_uid)) {
8125                         return USERSHARE_PATH_NOT_ALLOWED;
8126                 }
8127         }
8128
8129         *pp_sharepath = sharepath;
8130         *pp_comment = comment;
8131         return USERSHARE_OK;
8132 }
8133
8134 /***************************************************************************
8135  Deal with a usershare file.
8136  Returns:
8137         >= 0 - snum
8138         -1 - Bad name, invalid contents.
8139            - service name already existed and not a usershare, problem
8140             with permissions to share directory etc.
8141 ***************************************************************************/
8142
8143 static int process_usershare_file(const char *dir_name, const char *file_name, int snum_template)
8144 {
8145         SMB_STRUCT_STAT sbuf;
8146         SMB_STRUCT_STAT lsbuf;
8147         char *fname = NULL;
8148         char *sharepath = NULL;
8149         char *comment = NULL;
8150         fstring service_name;
8151         char **lines = NULL;
8152         int numlines = 0;
8153         int fd = -1;
8154         int iService = -1;
8155         TALLOC_CTX *ctx = NULL;
8156         SEC_DESC *psd = NULL;
8157         bool guest_ok = False;
8158
8159         /* Ensure share name doesn't contain invalid characters. */
8160         if (!validate_net_name(file_name, INVALID_SHARENAME_CHARS, strlen(file_name))) {
8161                 DEBUG(0,("process_usershare_file: share name %s contains "
8162                         "invalid characters (any of %s)\n",
8163                         file_name, INVALID_SHARENAME_CHARS ));
8164                 return -1;
8165         }
8166
8167         fstrcpy(service_name, file_name);
8168
8169         if (asprintf(&fname, "%s/%s", dir_name, file_name) < 0) {
8170         }
8171
8172         /* Minimize the race condition by doing an lstat before we
8173            open and fstat. Ensure this isn't a symlink link. */
8174
8175         if (sys_lstat(fname, &lsbuf) != 0) {
8176                 DEBUG(0,("process_usershare_file: stat of %s failed. %s\n",
8177                         fname, strerror(errno) ));
8178                 SAFE_FREE(fname);
8179                 return -1;
8180         }
8181
8182         /* This must be a regular file, not a symlink, directory or
8183            other strange filetype. */
8184         if (!check_usershare_stat(fname, &lsbuf)) {
8185                 SAFE_FREE(fname);
8186                 return -1;
8187         }
8188
8189         {
8190                 char *canon_name = canonicalize_servicename(service_name);
8191                 TDB_DATA data = dbwrap_fetch_bystring(
8192                         ServiceHash, canon_name, canon_name);
8193
8194                 iService = -1;
8195
8196                 if ((data.dptr != NULL) && (data.dsize == sizeof(iService))) {
8197                         iService = *(int *)data.dptr;
8198                 }
8199                 TALLOC_FREE(canon_name);
8200         }
8201
8202         if (iService != -1 && ServicePtrs[iService]->usershare_last_mod == lsbuf.st_mtime) {
8203                 /* Nothing changed - Mark valid and return. */
8204                 DEBUG(10,("process_usershare_file: service %s not changed.\n",
8205                         service_name ));
8206                 ServicePtrs[iService]->usershare = USERSHARE_VALID;
8207                 SAFE_FREE(fname);
8208                 return iService;
8209         }
8210
8211         /* Try and open the file read only - no symlinks allowed. */
8212 #ifdef O_NOFOLLOW
8213         fd = sys_open(fname, O_RDONLY|O_NOFOLLOW, 0);
8214 #else
8215         fd = sys_open(fname, O_RDONLY, 0);
8216 #endif
8217
8218         if (fd == -1) {
8219                 DEBUG(0,("process_usershare_file: unable to open %s. %s\n",
8220                         fname, strerror(errno) ));
8221                 SAFE_FREE(fname);
8222                 return -1;
8223         }
8224
8225         /* Now fstat to be *SURE* it's a regular file. */
8226         if (sys_fstat(fd, &sbuf) != 0) {
8227                 close(fd);
8228                 DEBUG(0,("process_usershare_file: fstat of %s failed. %s\n",
8229                         fname, strerror(errno) ));
8230                 SAFE_FREE(fname);
8231                 return -1;
8232         }
8233
8234         /* Is it the same dev/inode as was lstated ? */
8235         if (lsbuf.st_dev != sbuf.st_dev || lsbuf.st_ino != sbuf.st_ino) {
8236                 close(fd);
8237                 DEBUG(0,("process_usershare_file: fstat of %s is a different file from lstat. "
8238                         "Symlink spoofing going on ?\n", fname ));
8239                 SAFE_FREE(fname);
8240                 return -1;
8241         }
8242
8243         /* This must be a regular file, not a symlink, directory or
8244            other strange filetype. */
8245         if (!check_usershare_stat(fname, &sbuf)) {
8246                 SAFE_FREE(fname);
8247                 return -1;
8248         }
8249
8250         lines = fd_lines_load(fd, &numlines, MAX_USERSHARE_FILE_SIZE);
8251
8252         close(fd);
8253         if (lines == NULL) {
8254                 DEBUG(0,("process_usershare_file: loading file %s owned by %u failed.\n",
8255                         fname, (unsigned int)sbuf.st_uid ));
8256                 SAFE_FREE(fname);
8257                 return -1;
8258         }
8259
8260         SAFE_FREE(fname);
8261
8262         /* Should we allow printers to be shared... ? */
8263         ctx = talloc_init("usershare_sd_xctx");
8264         if (!ctx) {
8265                 file_lines_free(lines);
8266                 return 1;
8267         }
8268
8269         if (parse_usershare_file(ctx, &sbuf, service_name,
8270                         iService, lines, numlines, &sharepath,
8271                         &comment, &psd, &guest_ok) != USERSHARE_OK) {
8272                 talloc_destroy(ctx);
8273                 file_lines_free(lines);
8274                 return -1;
8275         }
8276
8277         file_lines_free(lines);
8278
8279         /* Everything ok - add the service possibly using a template. */
8280         if (iService < 0) {
8281                 const struct service *sp = &sDefault;
8282                 if (snum_template != -1) {
8283                         sp = ServicePtrs[snum_template];
8284                 }
8285
8286                 if ((iService = add_a_service(sp, service_name)) < 0) {
8287                         DEBUG(0, ("process_usershare_file: Failed to add "
8288                                 "new service %s\n", service_name));
8289                         talloc_destroy(ctx);
8290                         return -1;
8291                 }
8292
8293                 /* Read only is controlled by usershare ACL below. */
8294                 ServicePtrs[iService]->bRead_only = False;
8295         }
8296
8297         /* Write the ACL of the new/modified share. */
8298         if (!set_share_security(service_name, psd)) {
8299                  DEBUG(0, ("process_usershare_file: Failed to set share "
8300                         "security for user share %s\n",
8301                         service_name ));
8302                 lp_remove_service(iService);
8303                 talloc_destroy(ctx);
8304                 return -1;
8305         }
8306
8307         /* If from a template it may be marked invalid. */
8308         ServicePtrs[iService]->valid = True;
8309
8310         /* Set the service as a valid usershare. */
8311         ServicePtrs[iService]->usershare = USERSHARE_VALID;
8312
8313         /* Set guest access. */
8314         if (lp_usershare_allow_guests()) {
8315                 ServicePtrs[iService]->bGuest_ok = guest_ok;
8316         }
8317
8318         /* And note when it was loaded. */
8319         ServicePtrs[iService]->usershare_last_mod = sbuf.st_mtime;
8320         string_set(&ServicePtrs[iService]->szPath, sharepath);
8321         string_set(&ServicePtrs[iService]->comment, comment);
8322
8323         talloc_destroy(ctx);
8324
8325         return iService;
8326 }
8327
8328 /***************************************************************************
8329  Checks if a usershare entry has been modified since last load.
8330 ***************************************************************************/
8331
8332 static bool usershare_exists(int iService, time_t *last_mod)
8333 {
8334         SMB_STRUCT_STAT lsbuf;
8335         const char *usersharepath = Globals.szUsersharePath;
8336         char *fname;
8337
8338         if (asprintf(&fname, "%s/%s",
8339                                 usersharepath,
8340                                 ServicePtrs[iService]->szService) < 0) {
8341                 return false;
8342         }
8343
8344         if (sys_lstat(fname, &lsbuf) != 0) {
8345                 SAFE_FREE(fname);
8346                 return false;
8347         }
8348
8349         if (!S_ISREG(lsbuf.st_mode)) {
8350                 SAFE_FREE(fname);
8351                 return false;
8352         }
8353
8354         SAFE_FREE(fname);
8355         *last_mod = lsbuf.st_mtime;
8356         return true;
8357 }
8358
8359 /***************************************************************************
8360  Load a usershare service by name. Returns a valid servicenumber or -1.
8361 ***************************************************************************/
8362
8363 int load_usershare_service(const char *servicename)
8364 {
8365         SMB_STRUCT_STAT sbuf;
8366         const char *usersharepath = Globals.szUsersharePath;
8367         int max_user_shares = Globals.iUsershareMaxShares;
8368         int snum_template = -1;
8369
8370         if (*usersharepath == 0 ||  max_user_shares == 0) {
8371                 return -1;
8372         }
8373
8374         if (sys_stat(usersharepath, &sbuf) != 0) {
8375                 DEBUG(0,("load_usershare_service: stat of %s failed. %s\n",
8376                         usersharepath, strerror(errno) ));
8377                 return -1;
8378         }
8379
8380         if (!S_ISDIR(sbuf.st_mode)) {
8381                 DEBUG(0,("load_usershare_service: %s is not a directory.\n",
8382                         usersharepath ));
8383                 return -1;
8384         }
8385
8386         /*
8387          * This directory must be owned by root, and have the 't' bit set.
8388          * It also must not be writable by "other".
8389          */
8390
8391 #ifdef S_ISVTX
8392         if (sbuf.st_uid != 0 || !(sbuf.st_mode & S_ISVTX) || (sbuf.st_mode & S_IWOTH)) {
8393 #else
8394         if (sbuf.st_uid != 0 || (sbuf.st_mode & S_IWOTH)) {
8395 #endif
8396                 DEBUG(0,("load_usershare_service: directory %s is not owned by root "
8397                         "or does not have the sticky bit 't' set or is writable by anyone.\n",
8398                         usersharepath ));
8399                 return -1;
8400         }
8401
8402         /* Ensure the template share exists if it's set. */
8403         if (Globals.szUsershareTemplateShare[0]) {
8404                 /* We can't use lp_servicenumber here as we are recommending that
8405                    template shares have -valid=False set. */
8406                 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
8407                         if (ServicePtrs[snum_template]->szService &&
8408                                         strequal(ServicePtrs[snum_template]->szService,
8409                                                 Globals.szUsershareTemplateShare)) {
8410                                 break;
8411                         }
8412                 }
8413
8414                 if (snum_template == -1) {
8415                         DEBUG(0,("load_usershare_service: usershare template share %s "
8416                                 "does not exist.\n",
8417                                 Globals.szUsershareTemplateShare ));
8418                         return -1;
8419                 }
8420         }
8421
8422         return process_usershare_file(usersharepath, servicename, snum_template);
8423 }
8424
8425 /***************************************************************************
8426  Load all user defined shares from the user share directory.
8427  We only do this if we're enumerating the share list.
8428  This is the function that can delete usershares that have
8429  been removed.
8430 ***************************************************************************/
8431
8432 int load_usershare_shares(void)
8433 {
8434         SMB_STRUCT_DIR *dp;
8435         SMB_STRUCT_STAT sbuf;
8436         SMB_STRUCT_DIRENT *de;
8437         int num_usershares = 0;
8438         int max_user_shares = Globals.iUsershareMaxShares;
8439         unsigned int num_dir_entries, num_bad_dir_entries, num_tmp_dir_entries;
8440         unsigned int allowed_bad_entries = ((2*max_user_shares)/10);
8441         unsigned int allowed_tmp_entries = ((2*max_user_shares)/10);
8442         int iService;
8443         int snum_template = -1;
8444         const char *usersharepath = Globals.szUsersharePath;
8445         int ret = lp_numservices();
8446
8447         if (max_user_shares == 0 || *usersharepath == '\0') {
8448                 return lp_numservices();
8449         }
8450
8451         if (sys_stat(usersharepath, &sbuf) != 0) {
8452                 DEBUG(0,("load_usershare_shares: stat of %s failed. %s\n",
8453                         usersharepath, strerror(errno) ));
8454                 return ret;
8455         }
8456
8457         /*
8458          * This directory must be owned by root, and have the 't' bit set.
8459          * It also must not be writable by "other".
8460          */
8461
8462 #ifdef S_ISVTX
8463         if (sbuf.st_uid != 0 || !(sbuf.st_mode & S_ISVTX) || (sbuf.st_mode & S_IWOTH)) {
8464 #else
8465         if (sbuf.st_uid != 0 || (sbuf.st_mode & S_IWOTH)) {
8466 #endif
8467                 DEBUG(0,("load_usershare_shares: directory %s is not owned by root "
8468                         "or does not have the sticky bit 't' set or is writable by anyone.\n",
8469                         usersharepath ));
8470                 return ret;
8471         }
8472
8473         /* Ensure the template share exists if it's set. */
8474         if (Globals.szUsershareTemplateShare[0]) {
8475                 /* We can't use lp_servicenumber here as we are recommending that
8476                    template shares have -valid=False set. */
8477                 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
8478                         if (ServicePtrs[snum_template]->szService &&
8479                                         strequal(ServicePtrs[snum_template]->szService,
8480                                                 Globals.szUsershareTemplateShare)) {
8481                                 break;
8482                         }
8483                 }
8484
8485                 if (snum_template == -1) {
8486                         DEBUG(0,("load_usershare_shares: usershare template share %s "
8487                                 "does not exist.\n",
8488                                 Globals.szUsershareTemplateShare ));
8489                         return ret;
8490                 }
8491         }
8492
8493         /* Mark all existing usershares as pending delete. */
8494         for (iService = iNumServices - 1; iService >= 0; iService--) {
8495                 if (VALID(iService) && ServicePtrs[iService]->usershare) {
8496                         ServicePtrs[iService]->usershare = USERSHARE_PENDING_DELETE;
8497                 }
8498         }
8499
8500         dp = sys_opendir(usersharepath);
8501         if (!dp) {
8502                 DEBUG(0,("load_usershare_shares:: failed to open directory %s. %s\n",
8503                         usersharepath, strerror(errno) ));
8504                 return ret;
8505         }
8506
8507         for (num_dir_entries = 0, num_bad_dir_entries = 0, num_tmp_dir_entries = 0;
8508                         (de = sys_readdir(dp));
8509                         num_dir_entries++ ) {
8510                 int r;
8511                 const char *n = de->d_name;
8512
8513                 /* Ignore . and .. */
8514                 if (*n == '.') {
8515                         if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) {
8516                                 continue;
8517                         }
8518                 }
8519
8520                 if (n[0] == ':') {
8521                         /* Temporary file used when creating a share. */
8522                         num_tmp_dir_entries++;
8523                 }
8524
8525                 /* Allow 20% tmp entries. */
8526                 if (num_tmp_dir_entries > allowed_tmp_entries) {
8527                         DEBUG(0,("load_usershare_shares: too many temp entries (%u) "
8528                                 "in directory %s\n",
8529                                 num_tmp_dir_entries, usersharepath));
8530                         break;
8531                 }
8532
8533                 r = process_usershare_file(usersharepath, n, snum_template);
8534                 if (r == 0) {
8535                         /* Update the services count. */
8536                         num_usershares++;
8537                         if (num_usershares >= max_user_shares) {
8538                                 DEBUG(0,("load_usershare_shares: max user shares reached "
8539                                         "on file %s in directory %s\n",
8540                                         n, usersharepath ));
8541                                 break;
8542                         }
8543                 } else if (r == -1) {
8544                         num_bad_dir_entries++;
8545                 }
8546
8547                 /* Allow 20% bad entries. */
8548                 if (num_bad_dir_entries > allowed_bad_entries) {
8549                         DEBUG(0,("load_usershare_shares: too many bad entries (%u) "
8550                                 "in directory %s\n",
8551                                 num_bad_dir_entries, usersharepath));
8552                         break;
8553                 }
8554
8555                 /* Allow 20% bad entries. */
8556                 if (num_dir_entries > max_user_shares + allowed_bad_entries) {
8557                         DEBUG(0,("load_usershare_shares: too many total entries (%u) "
8558                         "in directory %s\n",
8559                         num_dir_entries, usersharepath));
8560                         break;
8561                 }
8562         }
8563
8564         sys_closedir(dp);
8565
8566         /* Sweep through and delete any non-refreshed usershares that are
8567            not currently in use. */
8568         for (iService = iNumServices - 1; iService >= 0; iService--) {
8569                 if (VALID(iService) && (ServicePtrs[iService]->usershare == USERSHARE_PENDING_DELETE)) {
8570                         if (conn_snum_used(iService)) {
8571                                 continue;
8572                         }
8573                         /* Remove from the share ACL db. */
8574                         DEBUG(10,("load_usershare_shares: Removing deleted usershare %s\n",
8575                                 lp_servicename(iService) ));
8576                         delete_share_security(lp_servicename(iService));
8577                         free_service_byindex(iService);
8578                 }
8579         }
8580
8581         return lp_numservices();
8582 }
8583
8584 /********************************************************
8585  Destroy global resources allocated in this file
8586 ********************************************************/
8587
8588 void gfree_loadparm(void)
8589 {
8590         struct file_lists *f;
8591         struct file_lists *next;
8592         int i;
8593
8594         /* Free the file lists */
8595
8596         f = file_lists;
8597         while( f ) {
8598                 next = f->next;
8599                 SAFE_FREE( f->name );
8600                 SAFE_FREE( f->subfname );
8601                 SAFE_FREE( f );
8602                 f = next;
8603         }
8604
8605         /* Free resources allocated to services */
8606
8607         for ( i = 0; i < iNumServices; i++ ) {
8608                 if ( VALID(i) ) {
8609                         free_service_byindex(i);
8610                 }
8611         }
8612
8613         SAFE_FREE( ServicePtrs );
8614         iNumServices = 0;
8615
8616         /* Now release all resources allocated to global
8617            parameters and the default service */
8618
8619         for (i = 0; parm_table[i].label; i++) 
8620         {
8621                 if ( parm_table[i].type == P_STRING 
8622                         || parm_table[i].type == P_USTRING ) 
8623                 {
8624                         string_free( (char**)parm_table[i].ptr );
8625                 }
8626                 else if (parm_table[i].type == P_LIST) {
8627                         TALLOC_FREE( *((char***)parm_table[i].ptr) );
8628                 }
8629         }
8630 }
8631
8632
8633 /***************************************************************************
8634  Allow client apps to specify that they are a client
8635 ***************************************************************************/
8636 void lp_set_in_client(bool b)
8637 {
8638     in_client = b;
8639 }
8640
8641
8642 /***************************************************************************
8643  Determine if we're running in a client app
8644 ***************************************************************************/
8645 bool lp_is_in_client(void)
8646 {
8647     return in_client;
8648 }
8649
8650
8651
8652
8653 /***************************************************************************
8654  Load the services array from the services file. Return True on success, 
8655  False on failure.
8656 ***************************************************************************/
8657
8658 bool lp_load_ex(const char *pszFname,
8659                 bool global_only,
8660                 bool save_defaults,
8661                 bool add_ipc,
8662                 bool initialize_globals,
8663                 bool no_includes)
8664 {
8665         char *n2 = NULL;
8666         bool bRetval;
8667         param_opt_struct *data, *pdata;
8668
8669         bRetval = False;
8670
8671         DEBUG(3, ("lp_load_ex: refreshing parameters\n"));
8672
8673         bInGlobalSection = True;
8674         bGlobalOnly = global_only;
8675         bNoIncludes = no_includes;
8676
8677         init_globals(! initialize_globals);
8678         debug_init();
8679
8680         if (save_defaults) {
8681                 init_locals();
8682                 lp_save_defaults();
8683         }
8684
8685         if (Globals.param_opt != NULL) {
8686                 data = Globals.param_opt;
8687                 while (data) {
8688                         string_free(&data->key);
8689                         string_free(&data->value);
8690                         TALLOC_FREE(data->list);
8691                         pdata = data->next;
8692                         SAFE_FREE(data);
8693                         data = pdata;
8694                 }
8695                 Globals.param_opt = NULL;
8696         }
8697
8698         if (lp_config_backend_is_file()) {
8699                 n2 = alloc_sub_basic(get_current_username(),
8700                                         current_user_info.domain,
8701                                         pszFname);
8702                 if (!n2) {
8703                         smb_panic("lp_load_ex: out of memory");
8704                 }
8705
8706                 add_to_file_list(pszFname, n2);
8707
8708                 /* We get sections first, so have to start 'behind' to make up */
8709                 iServiceIndex = -1;
8710                 bRetval = pm_process(n2, do_section, do_parameter, NULL);
8711                 SAFE_FREE(n2);
8712
8713                 /* finish up the last section */
8714                 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
8715                 if (bRetval) {
8716                         if (iServiceIndex >= 0) {
8717                                 bRetval = service_ok(iServiceIndex);
8718                         }
8719                 }
8720
8721                 if (lp_config_backend_is_registry()) {
8722                         /* config backend changed to registry in config file */
8723                         /*
8724                          * We need to use this extra global variable here to
8725                          * survive restart: init_globals uses this as a default
8726                          * for ConfigBackend. Otherwise, init_globals would
8727                          *  send us into an endless loop here.
8728                          */
8729                         config_backend = CONFIG_BACKEND_REGISTRY;
8730                         /* start over */
8731                         DEBUG(1, ("lp_load_ex: changing to config backend "
8732                                   "registry\n"));
8733                         init_globals(false);
8734                         lp_kill_all_services();
8735                         return lp_load_ex(pszFname, global_only, save_defaults,
8736                                           add_ipc, initialize_globals, no_includes);
8737                 }
8738         } else if (lp_config_backend_is_registry()) {
8739                 bRetval = process_registry_globals();
8740         } else {
8741                 DEBUG(0, ("Illegal config  backend given: %d\n",
8742                           lp_config_backend()));
8743                 bRetval = false;
8744         }
8745
8746         lp_add_auto_services(lp_auto_services());
8747
8748         if (add_ipc) {
8749                 /* When 'restrict anonymous = 2' guest connections to ipc$
8750                    are denied */
8751                 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
8752                 if ( lp_enable_asu_support() ) {
8753                         lp_add_ipc("ADMIN$", false);
8754                 }
8755         }
8756
8757         set_server_role();
8758         set_default_server_announce_type();
8759         set_allowed_client_auth();
8760
8761         bLoaded = True;
8762
8763         /* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */
8764         /* if bWINSsupport is true and we are in the client            */
8765         if (lp_is_in_client() && Globals.bWINSsupport) {
8766                 lp_do_parameter(GLOBAL_SECTION_SNUM, "wins server", "127.0.0.1");
8767         }
8768
8769         init_iconv();
8770
8771         bNoIncludes = false;
8772
8773         return (bRetval);
8774 }
8775
8776 bool lp_load(const char *pszFname,
8777              bool global_only,
8778              bool save_defaults,
8779              bool add_ipc,
8780              bool initialize_globals)
8781 {
8782         return lp_load_ex(pszFname,
8783                           global_only,
8784                           save_defaults,
8785                           add_ipc,
8786                           initialize_globals,
8787                           false);
8788 }
8789
8790 bool lp_load_initial_only(const char *pszFname)
8791 {
8792         return lp_load_ex(pszFname,
8793                           true,
8794                           false,
8795                           false,
8796                           true,
8797                           true);
8798 }
8799
8800 /***************************************************************************
8801  Reset the max number of services.
8802 ***************************************************************************/
8803
8804 void lp_resetnumservices(void)
8805 {
8806         iNumServices = 0;
8807 }
8808
8809 /***************************************************************************
8810  Return the max number of services.
8811 ***************************************************************************/
8812
8813 int lp_numservices(void)
8814 {
8815         return (iNumServices);
8816 }
8817
8818 /***************************************************************************
8819 Display the contents of the services array in human-readable form.
8820 ***************************************************************************/
8821
8822 void lp_dump(FILE *f, bool show_defaults, int maxtoprint)
8823 {
8824         int iService;
8825
8826         if (show_defaults)
8827                 defaults_saved = False;
8828
8829         dump_globals(f);
8830
8831         dump_a_service(&sDefault, f);
8832
8833         for (iService = 0; iService < maxtoprint; iService++) {
8834                 fprintf(f,"\n");
8835                 lp_dump_one(f, show_defaults, iService);
8836         }
8837 }
8838
8839 /***************************************************************************
8840 Display the contents of one service in human-readable form.
8841 ***************************************************************************/
8842
8843 void lp_dump_one(FILE * f, bool show_defaults, int snum)
8844 {
8845         if (VALID(snum)) {
8846                 if (ServicePtrs[snum]->szService[0] == '\0')
8847                         return;
8848                 dump_a_service(ServicePtrs[snum], f);
8849         }
8850 }
8851
8852 /***************************************************************************
8853 Return the number of the service with the given name, or -1 if it doesn't
8854 exist. Note that this is a DIFFERENT ANIMAL from the internal function
8855 getservicebyname()! This works ONLY if all services have been loaded, and
8856 does not copy the found service.
8857 ***************************************************************************/
8858
8859 int lp_servicenumber(const char *pszServiceName)
8860 {
8861         int iService;
8862         fstring serviceName;
8863         
8864         if (!pszServiceName) {
8865                 return GLOBAL_SECTION_SNUM;
8866         }
8867         
8868         for (iService = iNumServices - 1; iService >= 0; iService--) {
8869                 if (VALID(iService) && ServicePtrs[iService]->szService) {
8870                         /*
8871                          * The substitution here is used to support %U is
8872                          * service names
8873                          */
8874                         fstrcpy(serviceName, ServicePtrs[iService]->szService);
8875                         standard_sub_basic(get_current_username(),
8876                                            current_user_info.domain,
8877                                            serviceName,sizeof(serviceName));
8878                         if (strequal(serviceName, pszServiceName)) {
8879                                 break;
8880                         }
8881                 }
8882         }
8883
8884         if (iService >= 0 && ServicePtrs[iService]->usershare == USERSHARE_VALID) {
8885                 time_t last_mod;
8886
8887                 if (!usershare_exists(iService, &last_mod)) {
8888                         /* Remove the share security tdb entry for it. */
8889                         delete_share_security(lp_servicename(iService));
8890                         /* Remove it from the array. */
8891                         free_service_byindex(iService);
8892                         /* Doesn't exist anymore. */
8893                         return GLOBAL_SECTION_SNUM;
8894                 }
8895
8896                 /* Has it been modified ? If so delete and reload. */
8897                 if (ServicePtrs[iService]->usershare_last_mod < last_mod) {
8898                         /* Remove it from the array. */
8899                         free_service_byindex(iService);
8900                         /* and now reload it. */
8901                         iService = load_usershare_service(pszServiceName);
8902                 }
8903         }
8904
8905         if (iService < 0) {
8906                 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
8907                 return GLOBAL_SECTION_SNUM;
8908         }
8909
8910         return (iService);
8911 }
8912
8913 bool share_defined(const char *service_name)
8914 {
8915         return (lp_servicenumber(service_name) != -1);
8916 }
8917
8918 struct share_params *get_share_params(TALLOC_CTX *mem_ctx,
8919                                       const char *sharename)
8920 {
8921         struct share_params *result;
8922         char *sname;
8923         int snum;
8924
8925         if (!(sname = SMB_STRDUP(sharename))) {
8926                 return NULL;
8927         }
8928
8929         snum = find_service(sname);
8930         SAFE_FREE(sname);
8931
8932         if (snum < 0) {
8933                 return NULL;
8934         }
8935
8936         if (!(result = TALLOC_P(mem_ctx, struct share_params))) {
8937                 DEBUG(0, ("talloc failed\n"));
8938                 return NULL;
8939         }
8940
8941         result->service = snum;
8942         return result;
8943 }
8944
8945 struct share_iterator *share_list_all(TALLOC_CTX *mem_ctx)
8946 {
8947         struct share_iterator *result;
8948
8949         if (!(result = TALLOC_P(mem_ctx, struct share_iterator))) {
8950                 DEBUG(0, ("talloc failed\n"));
8951                 return NULL;
8952         }
8953
8954         result->next_id = 0;
8955         return result;
8956 }
8957
8958 struct share_params *next_share(struct share_iterator *list)
8959 {
8960         struct share_params *result;
8961
8962         while (!lp_snum_ok(list->next_id) &&
8963                (list->next_id < lp_numservices())) {
8964                 list->next_id += 1;
8965         }
8966
8967         if (list->next_id >= lp_numservices()) {
8968                 return NULL;
8969         }
8970
8971         if (!(result = TALLOC_P(list, struct share_params))) {
8972                 DEBUG(0, ("talloc failed\n"));
8973                 return NULL;
8974         }
8975
8976         result->service = list->next_id;
8977         list->next_id += 1;
8978         return result;
8979 }
8980
8981 struct share_params *next_printer(struct share_iterator *list)
8982 {
8983         struct share_params *result;
8984
8985         while ((result = next_share(list)) != NULL) {
8986                 if (lp_print_ok(result->service)) {
8987                         break;
8988                 }
8989         }
8990         return result;
8991 }
8992
8993 /*
8994  * This is a hack for a transition period until we transformed all code from
8995  * service numbers to struct share_params.
8996  */
8997
8998 struct share_params *snum2params_static(int snum)
8999 {
9000         static struct share_params result;
9001         result.service = snum;
9002         return &result;
9003 }
9004
9005 /*******************************************************************
9006  A useful volume label function. 
9007 ********************************************************************/
9008
9009 const char *volume_label(int snum)
9010 {
9011         char *ret;
9012         const char *label = lp_volume(snum);
9013         if (!*label) {
9014                 label = lp_servicename(snum);
9015         }
9016                 
9017         /* This returns a 33 byte guarenteed null terminated string. */
9018         ret = talloc_strndup(talloc_tos(), label, 32);
9019         if (!ret) {
9020                 return "";
9021         }               
9022         return ret;
9023 }
9024
9025 /*******************************************************************
9026  Set the server type we will announce as via nmbd.
9027 ********************************************************************/
9028
9029 static void set_default_server_announce_type(void)
9030 {
9031         default_server_announce = 0;
9032         default_server_announce |= SV_TYPE_WORKSTATION;
9033         default_server_announce |= SV_TYPE_SERVER;
9034         default_server_announce |= SV_TYPE_SERVER_UNIX;
9035
9036         /* note that the flag should be set only if we have a 
9037            printer service but nmbd doesn't actually load the 
9038            services so we can't tell   --jerry */
9039
9040         default_server_announce |= SV_TYPE_PRINTQ_SERVER;
9041
9042         switch (lp_announce_as()) {
9043                 case ANNOUNCE_AS_NT_SERVER:
9044                         default_server_announce |= SV_TYPE_SERVER_NT;
9045                         /* fall through... */
9046                 case ANNOUNCE_AS_NT_WORKSTATION:
9047                         default_server_announce |= SV_TYPE_NT;
9048                         break;
9049                 case ANNOUNCE_AS_WIN95:
9050                         default_server_announce |= SV_TYPE_WIN95_PLUS;
9051                         break;
9052                 case ANNOUNCE_AS_WFW:
9053                         default_server_announce |= SV_TYPE_WFW;
9054                         break;
9055                 default:
9056                         break;
9057         }
9058
9059         switch (lp_server_role()) {
9060                 case ROLE_DOMAIN_MEMBER:
9061                         default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
9062                         break;
9063                 case ROLE_DOMAIN_PDC:
9064                         default_server_announce |= SV_TYPE_DOMAIN_CTRL;
9065                         break;
9066                 case ROLE_DOMAIN_BDC:
9067                         default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
9068                         break;
9069                 case ROLE_STANDALONE:
9070                 default:
9071                         break;
9072         }
9073         if (lp_time_server())
9074                 default_server_announce |= SV_TYPE_TIME_SOURCE;
9075
9076         if (lp_host_msdfs())
9077                 default_server_announce |= SV_TYPE_DFS_SERVER;
9078 }
9079
9080 /***********************************************************
9081  returns role of Samba server
9082 ************************************************************/
9083
9084 int lp_server_role(void)
9085 {
9086         return server_role;
9087 }
9088
9089 /***********************************************************
9090  If we are PDC then prefer us as DMB
9091 ************************************************************/
9092
9093 bool lp_domain_master(void)
9094 {
9095         if (Globals.iDomainMaster == Auto)
9096                 return (lp_server_role() == ROLE_DOMAIN_PDC);
9097
9098         return (bool)Globals.iDomainMaster;
9099 }
9100
9101 /***********************************************************
9102  If we are DMB then prefer us as LMB
9103 ************************************************************/
9104
9105 bool lp_preferred_master(void)
9106 {
9107         if (Globals.iPreferredMaster == Auto)
9108                 return (lp_local_master() && lp_domain_master());
9109
9110         return (bool)Globals.iPreferredMaster;
9111 }
9112
9113 /*******************************************************************
9114  Remove a service.
9115 ********************************************************************/
9116
9117 void lp_remove_service(int snum)
9118 {
9119         ServicePtrs[snum]->valid = False;
9120         invalid_services[num_invalid_services++] = snum;
9121 }
9122
9123 /*******************************************************************
9124  Copy a service.
9125 ********************************************************************/
9126
9127 void lp_copy_service(int snum, const char *new_name)
9128 {
9129         do_section(new_name, NULL);
9130         if (snum >= 0) {
9131                 snum = lp_servicenumber(new_name);
9132                 if (snum >= 0)
9133                         lp_do_parameter(snum, "copy", lp_servicename(snum));
9134         }
9135 }
9136
9137
9138 /*******************************************************************
9139  Get the default server type we will announce as via nmbd.
9140 ********************************************************************/
9141
9142 int lp_default_server_announce(void)
9143 {
9144         return default_server_announce;
9145 }
9146
9147 /*******************************************************************
9148  Split the announce version into major and minor numbers.
9149 ********************************************************************/
9150
9151 int lp_major_announce_version(void)
9152 {
9153         static bool got_major = False;
9154         static int major_version = DEFAULT_MAJOR_VERSION;
9155         char *vers;
9156         char *p;
9157
9158         if (got_major)
9159                 return major_version;
9160
9161         got_major = True;
9162         if ((vers = lp_announce_version()) == NULL)
9163                 return major_version;
9164
9165         if ((p = strchr_m(vers, '.')) == 0)
9166                 return major_version;
9167
9168         *p = '\0';
9169         major_version = atoi(vers);
9170         return major_version;
9171 }
9172
9173 int lp_minor_announce_version(void)
9174 {
9175         static bool got_minor = False;
9176         static int minor_version = DEFAULT_MINOR_VERSION;
9177         char *vers;
9178         char *p;
9179
9180         if (got_minor)
9181                 return minor_version;
9182
9183         got_minor = True;
9184         if ((vers = lp_announce_version()) == NULL)
9185                 return minor_version;
9186
9187         if ((p = strchr_m(vers, '.')) == 0)
9188                 return minor_version;
9189
9190         p++;
9191         minor_version = atoi(p);
9192         return minor_version;
9193 }
9194
9195 /***********************************************************
9196  Set the global name resolution order (used in smbclient).
9197 ************************************************************/
9198
9199 void lp_set_name_resolve_order(const char *new_order)
9200 {
9201         string_set(&Globals.szNameResolveOrder, new_order);
9202 }
9203
9204 const char *lp_printername(int snum)
9205 {
9206         const char *ret = _lp_printername(snum);
9207         if (ret == NULL || (ret != NULL && *ret == '\0'))
9208                 ret = lp_const_servicename(snum);
9209
9210         return ret;
9211 }
9212
9213
9214 /***********************************************************
9215  Allow daemons such as winbindd to fix their logfile name.
9216 ************************************************************/
9217
9218 void lp_set_logfile(const char *name)
9219 {
9220         string_set(&Globals.szLogFile, name);
9221         debug_set_logfile(name);
9222 }
9223
9224 /*******************************************************************
9225  Return the max print jobs per queue.
9226 ********************************************************************/
9227
9228 int lp_maxprintjobs(int snum)
9229 {
9230         int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
9231         if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
9232                 maxjobs = PRINT_MAX_JOBID - 1;
9233
9234         return maxjobs;
9235 }
9236
9237 const char *lp_printcapname(void)
9238 {
9239         if ((Globals.szPrintcapname != NULL) &&
9240             (Globals.szPrintcapname[0] != '\0'))
9241                 return Globals.szPrintcapname;
9242
9243         if (sDefault.iPrinting == PRINT_CUPS) {
9244 #ifdef HAVE_CUPS
9245                 return "cups";
9246 #else
9247                 return "lpstat";
9248 #endif
9249         }
9250
9251         if (sDefault.iPrinting == PRINT_BSD)
9252                 return "/etc/printcap";
9253
9254         return PRINTCAP_NAME;
9255 }
9256
9257 /*******************************************************************
9258  Ensure we don't use sendfile if server smb signing is active.
9259 ********************************************************************/
9260
9261 static uint32 spoolss_state;
9262
9263 bool lp_disable_spoolss( void )
9264 {
9265         if ( spoolss_state == SVCCTL_STATE_UNKNOWN )
9266                 spoolss_state = _lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
9267
9268         return spoolss_state == SVCCTL_STOPPED ? True : False;
9269 }
9270
9271 void lp_set_spoolss_state( uint32 state )
9272 {
9273         SMB_ASSERT( (state == SVCCTL_STOPPED) || (state == SVCCTL_RUNNING) );
9274
9275         spoolss_state = state;
9276 }
9277
9278 uint32 lp_get_spoolss_state( void )
9279 {
9280         return lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
9281 }
9282
9283 /*******************************************************************
9284  Ensure we don't use sendfile if server smb signing is active.
9285 ********************************************************************/
9286
9287 bool lp_use_sendfile(int snum)
9288 {
9289         /* Using sendfile blows the brains out of any DOS or Win9x TCP stack... JRA. */
9290         if (Protocol < PROTOCOL_NT1) {
9291                 return False;
9292         }
9293         return (_lp_use_sendfile(snum) &&
9294                         (get_remote_arch() != RA_WIN95) &&
9295                         !srv_is_signing_active());
9296 }
9297
9298 /*******************************************************************
9299  Turn off sendfile if we find the underlying OS doesn't support it.
9300 ********************************************************************/
9301
9302 void set_use_sendfile(int snum, bool val)
9303 {
9304         if (LP_SNUM_OK(snum))
9305                 ServicePtrs[snum]->bUseSendfile = val;
9306         else
9307                 sDefault.bUseSendfile = val;
9308 }
9309
9310 /*******************************************************************
9311  Turn off storing DOS attributes if this share doesn't support it.
9312 ********************************************************************/
9313
9314 void set_store_dos_attributes(int snum, bool val)
9315 {
9316         if (!LP_SNUM_OK(snum))
9317                 return;
9318         ServicePtrs[(snum)]->bStoreDosAttributes = val;
9319 }
9320
9321 void lp_set_mangling_method(const char *new_method)
9322 {
9323         string_set(&Globals.szManglingMethod, new_method);
9324 }
9325
9326 /*******************************************************************
9327  Global state for POSIX pathname processing.
9328 ********************************************************************/
9329
9330 static bool posix_pathnames;
9331
9332 bool lp_posix_pathnames(void)
9333 {
9334         return posix_pathnames;
9335 }
9336
9337 /*******************************************************************
9338  Change everything needed to ensure POSIX pathname processing (currently
9339  not much).
9340 ********************************************************************/
9341
9342 void lp_set_posix_pathnames(void)
9343 {
9344         posix_pathnames = True;
9345 }
9346
9347 /*******************************************************************
9348  Global state for POSIX lock processing - CIFS unix extensions.
9349 ********************************************************************/
9350
9351 bool posix_default_lock_was_set;
9352 static enum brl_flavour posix_cifsx_locktype; /* By default 0 == WINDOWS_LOCK */
9353
9354 enum brl_flavour lp_posix_cifsu_locktype(files_struct *fsp)
9355 {
9356         if (posix_default_lock_was_set) {
9357                 return posix_cifsx_locktype;
9358         } else {
9359                 return fsp->posix_open ? POSIX_LOCK : WINDOWS_LOCK;
9360         }
9361 }
9362
9363 /*******************************************************************
9364 ********************************************************************/
9365
9366 void lp_set_posix_default_cifsx_readwrite_locktype(enum brl_flavour val)
9367 {
9368         posix_default_lock_was_set = True;
9369         posix_cifsx_locktype = val;
9370 }
9371
9372 int lp_min_receive_file_size(void)
9373 {
9374         if (Globals.iminreceivefile < 0) {
9375                 return 0;
9376         }
9377         return MIN(Globals.iminreceivefile, BUFFER_SIZE);
9378 }