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