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