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