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